nn.py 254.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
# Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
Y
Yu Yang 已提交
14
"""
15
All layers just related to the neural network.
Y
Yu Yang 已提交
16
"""
P
peizhilin 已提交
17
import os
S
sneaxiy 已提交
18
import inspect
19 20 21 22 23
import warnings

import numpy as np

import paddle
Y
Yu Yang 已提交
24
from ..layer_helper import LayerHelper
25
from paddle.fluid.framework import _in_legacy_dygraph
26
from ..initializer import Normal, Constant
27 28 29 30 31 32 33 34 35 36 37 38 39
from ..framework import (
    Variable,
    OpProtoHolder,
    _non_static_mode,
    dygraph_only,
    _dygraph_tracer,
    default_main_program,
    _varbase_creator,
    static_only,
    _global_flags,
    _in_legacy_dygraph,
    in_dygraph_mode,
)
40
from ..framework import _current_expected_place
41
from .. import dygraph_utils
Y
yangyaming 已提交
42
from ..param_attr import ParamAttr
43 44 45 46 47
from .layer_function_generator import (
    autodoc,
    templatedoc,
    _generate_doc_string_,
)
48
from .tensor import concat, assign, fill_constant, zeros, tensor_array_to_tensor
49
from . import utils
F
fengjiayi 已提交
50
from .. import unique_name
51
from functools import reduce
52
from .. import core
53
from ...utils import deprecated
54 55 56 57 58 59
from ..data_feeder import (
    convert_dtype,
    check_variable_and_dtype,
    check_type,
    check_dtype,
)
60
from paddle.utils import deprecated
61
from paddle import _C_ops, _legacy_C_ops
62 63
from collections.abc import Iterable

Y
Yu Yang 已提交
64 65

__all__ = [
X
Xin Pan 已提交
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
    'fc',
    'embedding',
    'linear_chain_crf',
    'crf_decoding',
    'conv2d',
    'pool2d',
    'batch_norm',
    'dropout',
    'split',
    'ctc_greedy_decoder',
    'l2_normalize',
    'matmul',
    'topk',
    'im2sequence',
    'row_conv',
    'multiplex',
    'layer_norm',
D
dengkaipeng 已提交
83
    'spectral_norm',
X
Xin Pan 已提交
84 85 86 87 88 89 90
    'smooth_l1',
    'one_hot',
    'autoincreased_step_counter',
    'unsqueeze',
    'lod_reset',
    'image_resize',
    'resize_bilinear',
K
Kaipeng Deng 已提交
91
    'resize_trilinear',
92
    'resize_nearest',
X
Xin Pan 已提交
93 94 95 96 97 98 99 100 101 102 103 104
    'relu',
    'elementwise_add',
    'elementwise_div',
    'elementwise_sub',
    'elementwise_mul',
    'gaussian_random',
    'sampling_id',
    'shape',
    'clip',
    'clip_by_norm',
    'mean',
    'mul',
M
minqiyang 已提交
105
    'hash',
D
dengkaipeng 已提交
106
    'grid_sampler',
G
gmcather 已提交
107
    'log_loss',
Q
Qiao Longfei 已提交
108
    'bilinear_tensor_product',
C
chengduo 已提交
109 110
    'merge_selected_rows',
    'get_tensor_from_selected_rows',
H
heqiaozhi 已提交
111
    'continuous_value_model',
112
    'unfold',
C
cjt222 已提交
113
    'deformable_roi_pooling',
114
    'shard_index',
H
huangjun12 已提交
115
    'hard_swish',
K
Kaipeng Deng 已提交
116
    'mish',
117
    'uniform_random',
myq406450149's avatar
myq406450149 已提交
118
    'unbind',
Y
Yu Yang 已提交
119 120
]

121
OP_NAMEMAPPING = {
122 123 124 125 126 127 128 129
    'elementwise_max': 'maximum',
    'elementwise_min': 'minimum',
    'elementwise_pow': 'elementwise_pow',
    'elementwise_floordiv': 'floor_divide',
    'elementwise_add': 'add',
    'elementwise_sub': 'subtract',
    'elementwise_mul': 'multiply',
    'elementwise_div': 'divide',
C
Chen Weihang 已提交
130
    'elementwise_mod': 'remainder',
131 132
}

Y
Yu Yang 已提交
133

134 135
def _get_reduce_dim(dim, input):
    """
136
    Internal function for reduce_sum, reduce_mean, reduce_prod.
137 138 139 140 141 142 143 144 145
    It computes the attribute reduce_all value based on axis.
    """
    if dim is not None and not isinstance(dim, list):
        if isinstance(dim, (tuple, range)):
            dim = list(dim)
        elif isinstance(dim, int):
            dim = [dim]
        else:
            raise TypeError(
146
                "The type of dim must be int, list, tuple or range, but received {}".format(
147
                    type(dim)
148 149
                )
            )
150 151 152 153 154 155 156 157 158 159
    if dim is None:
        dim = []
    if dim == [] or len(dim) == len(input.shape):
        reduce_all = True
    else:
        reduce_all = False

    return reduce_all, dim


160
@dygraph_only
161 162 163
def _elementwise_op_in_dygraph(
    x, y, axis=-1, act=None, use_mkldnn=False, op_name=None
):
164 165 166 167
    def is_inplace(op_name):
        return op_name[-1] == "_"

    if op_name not in OP_NAMEMAPPING.keys() or axis != -1:
168
        op = getattr(_legacy_C_ops, op_name)
169 170 171
        out = op(x, y, 'axis', axis, 'use_mkldnn', use_mkldnn)
    else:
        if in_dygraph_mode():
172 173
            op = getattr(
                _C_ops,
174 175
                OP_NAMEMAPPING[op_name] if not is_inplace(op_name) else op_name,
            )
176 177 178
            out = op(x, y)

        if _in_legacy_dygraph():
179
            op = getattr(_legacy_C_ops, op_name)
180
            out = op(x, y, 'axis', axis, 'use_mkldnn', use_mkldnn)
181 182 183 184 185 186 187 188 189 190 191 192 193 194
    return dygraph_utils._append_activation_in_dygraph(
        out, act, use_mkldnn=use_mkldnn
    )


def fc(
    input,
    size,
    num_flatten_dims=1,
    param_attr=None,
    bias_attr=None,
    act=None,
    name=None,
):
195
    r"""
196 197
    :api_attr: Static Graph

198
    **Fully Connected Layer**
Y
Yu Yang 已提交
199

200 201 202
    This operator creates a fully connected layer in the network. It can take
    a Tensor(or LoDTensor) or a list of Tensor(or LoDTensor) as its inputs(see
    Args in detail). It creates a variable called weight for each input Tensor,
203
    which represents a fully connected weight matrix from each input unit to
204 205 206 207
    each output unit. The fully connected layer multiplies each input Tensor
    with its corresponding weight to produce an output Tensor with shape :math:`[M, size]` ,
    where M is batch size. If a list of Tensor is given, the results of
    multiple output Tensors with shape :math:`[M, size]` will be summed up. If :attr:`bias_attr`
208
    is not None, a bias variable will be created and added to the output.
209
    Finally, if :attr:`act` is not None, it will be applied to the output as well.
C
caoying03 已提交
210

211
    When the input is a single Tensor(or LoDTensor):
C
caoying03 已提交
212

213 214 215 216
    .. math::

        Out = Act({XW + b})

217
    When the input is a list of Tensor(or LoDTensor):
218 219 220

    .. math::

221
        Out = Act({\sum_{i=0}^{N-1}X_iW_i + b})
222 223 224

    In the above equation:

225 226 227
    * :math:`N`: Number of the input. N equals to len(input) if input is list of Variable.
    * :math:`X_i`: The i-th input tensor.
    * :math:`W_i`: The i-th weights matrix corresponding i-th input tensor.
C
caoying03 已提交
228
    * :math:`b`: The bias parameter created by this layer (if needed).
229
    * :math:`Act`: The activation function.
230
    * :math:`Out`: The output Tensor.
231 232 233

    .. code-block:: text

234 235 236 237 238 239 240 241 242 243 244 245 246 247
        Case 1:
        Given a single Tensor data_1, and num_flatten_dims = 2:
            data_1.data = [[[0.1, 0.2],
                            [0.3, 0.4]]]
            data_1.shape = (1, 2, 2) # 1 is batch_size

            out = fluid.layers.fc(input=data_1, size=1, num_flatten_dims=2)

        Then output is:
            out.data = [[0.83234344], [0.34936576]]
            out.shape = (1, 2, 1)

        Case 2:
        Given a list of Tensor:
248 249 250 251 252 253 254 255 256 257 258 259 260
            data_1.data = [[[0.1, 0.2],
                           [0.3, 0.4]]]
            data_1.shape = (1, 2, 2) # 1 is batch_size

            data_2 = [[[0.1, 0.2, 0.3]]]
            data_2.shape = (1, 1, 3)

            out = fluid.layers.fc(input=[data_1, data_2], size=2)

        Then:
            out.data = [[0.18669507, 0.1893476]]
            out.shape = (1, 2)

Y
Yu Yang 已提交
261
    Args:
262 263 264
        input (Variable|list of Variable): A Tensor(or LoDTensor) with shape :math:`[N_1, N_2,..., N_k]` or
            a list of Tensor(or LoDTensor). The dimensions of the input Tensor is at least 2 and the data
            type should be float32 or float64.
T
tianshuo78520a 已提交
265
        size(int): The number of output units in this layer, which also means the feature size of output
266 267
            Tensor(or LoDTensor).
        num_flatten_dims (int): The fc layer can accept an input Tensor with more than
R
ranqiu 已提交
268
            two dimensions. If this happens, the multidimensional tensor will first be flattened
269 270
            into a 2-D matrix. The parameter :attr:`num_flatten_dims` determines how the input
            Tensor is flattened: the first :attr:`num_flatten_dims` (inclusive, index starts from 1)
R
ranqiu 已提交
271
            dimensions will be flatten to form the first dimension of the final matrix (height of
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
            the matrix), and the rest :math:`rank(X) - num\_flatten\_dims` dimensions are flattened to
            form the second dimension of the final matrix (width of the matrix). For example, assuming that
            X is a 5-dimensional Tensor with a shape [2, 3, 4, 5, 6], and :attr:`num_flatten_dims` = 3.
            Then, the flattened matrix will have a shape [2 x 3 x 4, 5 x 6] = [24, 30]. Default: 1.
        param_attr (ParamAttr): To specify the weight parameter property. Default: None, which means the
            default weight parameter property is used. See usage for details in :ref:`api_fluid_ParamAttr` .
        bias_attr (ParamAttr): To specify the bias parameter property. Default: None, which means the
            default bias parameter property is used. See usage for details in :ref:`api_fluid_ParamAttr` .
        act (str): Activation to be applied to the output of this layer, such as tanh, softmax,
            sigmoid, relu. For more information, please refer to :ref:`api_guide_activations_en` . Default: None.
        name (str, optional): The default value is None.  Normally there is no need for user to set this property.
            For more information, please refer to :ref:`api_guide_Name` .

    Returns:
        Variable: Tensor or LoDTensor calculated by fc layer. The data type is same with input.
287 288

    Raises:
289
        ValueError: If dimensions of the input Tensor is less than 2.
290 291 292 293

    Examples:
        .. code-block:: python

294
          import paddle.fluid as fluid
295 296
          import paddle
          paddle.enable_static()
297
          # when input is single tensor
298
          data = fluid.data(name="data", shape=[-1, 32], dtype="float32")
299
          fc = fluid.layers.fc(input=data, size=1000, act="tanh")
300 301

          # when input are multiple tensors
302 303
          data_1 = fluid.data(name="data_1", shape=[-1, 32], dtype="float32")
          data_2 = fluid.data(name="data_2", shape=[-1, 36], dtype="float32")
304
          fc = fluid.layers.fc(input=[data_1, data_2], size=1000, act="tanh")
Y
Yu Yang 已提交
305
    """
C
caoying03 已提交
306
    helper = LayerHelper("fc", **locals())
307
    check_type(input, 'input', (list, tuple, Variable), 'fc')
308 309
    if isinstance(input, (list, tuple)):
        for i, input_x in enumerate(input):
310
            check_type(input_x, 'input[' + str(i) + ']', Variable, 'fc')
Y
Yu Yang 已提交
311
    dtype = helper.input_dtype()
312 313 314
    check_dtype(
        dtype, 'input', ['float16', 'uint16', 'float32', 'float64'], 'fc'
    )
Y
Yu Yang 已提交
315
    mul_results = []
316 317
    for input_var, param_attr in helper.iter_inputs_and_params():
        input_shape = input_var.shape
318 319
        if num_flatten_dims == -1:
            num_flatten_dims = len(input_shape) - 1
Y
Yu Yang 已提交
320 321 322
        param_shape = [
            reduce(lambda a, b: a * b, input_shape[num_flatten_dims:], 1)
        ] + [size]
Y
ying 已提交
323

324 325 326
        w = helper.create_parameter(
            attr=param_attr, shape=param_shape, dtype=dtype, is_bias=False
        )
X
Xin Pan 已提交
327
        tmp = helper.create_variable_for_type_inference(dtype)
328 329 330 331 332 333
        helper.append_op(
            type="mul",
            inputs={"X": input_var, "Y": w},
            outputs={"Out": tmp},
            attrs={"x_num_col_dims": num_flatten_dims, "y_num_col_dims": 1},
        )
334 335 336 337
        mul_results.append(tmp)

    if len(mul_results) == 1:
        pre_bias = mul_results[0]
338
    else:
X
Xin Pan 已提交
339
        pre_bias = helper.create_variable_for_type_inference(dtype)
340 341 342 343 344 345
        helper.append_op(
            type="sum",
            inputs={"X": mul_results},
            outputs={"Out": pre_bias},
            attrs={"use_mkldnn": False},
        )
346 347 348 349
    # add bias
    pre_activation = helper.append_bias_op(pre_bias, dim_start=num_flatten_dims)
    # add activation
    return helper.append_activation(pre_activation)
Y
Yu Yang 已提交
350 351


T
tangwei12 已提交
352
@deprecated(since="2.0.0", update_to="paddle.nn.functional.embedding")
353 354 355 356 357 358 359 360 361
def embedding(
    input,
    size,
    is_sparse=False,
    is_distributed=False,
    padding_idx=None,
    param_attr=None,
    dtype='float32',
):
362
    r"""
363
    :api_attr: Static Graph
364

365 366 367 368 369 370 371 372 373 374 375 376
    **WARING:** This OP will be deprecated in a future release. This OP requires the
    last dimension of Tensor shape must be equal to 1. It is recommended to use
    fluid. :ref:`api_fluid_embedding` .

    The operator is used to lookup embeddings vector of ids provided by :attr:`input` .
    It automatically constructs a 2D embedding matrix based on the
    input :attr:`size` (vocab_size, emb_size) and :attr:`dtype` .

    This OP requires the last dimension of Tensor shape must be equal to 1. The shape
    of output Tensor is generated by replacing the last dimension of the input Tensor shape
    with emb_size.

377
    **Note:** The id in :attr:`input` must satisfy :math:`0 =< id < size[0]` ,
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
    otherwise the program will throw an exception and exit.

    .. code-block:: text

        Case 1:

        input is a Tensor. padding_idx = -1
            input.data = [[[1], [3]], [[2], [4]], [[4], [127]]]
            input.shape = [3, 2, 1]
        Given size = [128, 16]
        output is a Tensor:
            out.shape = [3, 2, 16]
            out.data = [[[0.129435295, 0.244512452, ..., 0.436322452],
                        [0.345421456, 0.524563927, ..., 0.144534654]],

                        [[0.345249859, 0.124939536, ..., 0.194353745],
                        [0.945345345, 0.435394634, ..., 0.435345365]],
395

396 397 398 399
                        [[0.945345345, 0.435394634, ..., 0.435345365],
                        [0.0,         0.0,         ..., 0.0        ]]]  # padding data
        The input padding_idx is less than 0, it is automatically converted to padding_idx = -1 + 128 = 127
        It will pad all-zero data when ids is 127.
400

401
        Case 2:
402

403 404 405 406 407 408 409 410 411 412 413 414 415 416
        input is a LoDTensor with 1-level LoD. padding_idx = 0
            input.lod = [[2, 3]]
            input.data = [[1], [3], [2], [4], [0]]
            input.shape = [5, 1]
        Given size = [128, 16]
        output is a LoDTensor:
            out.lod = [[2, 3]]
            out.shape = [5, 16]
            out.data = [[0.129435295, 0.244512452, ..., 0.436322452],
                        [0.345421456, 0.524563927, ..., 0.144534654],
                        [0.345249859, 0.124939536, ..., 0.194353745],
                        [0.945345345, 0.435394634, ..., 0.435345365],
                        [0.0,         0.0,         ..., 0.0        ]]  # padding data
        It will pad all-zero data when ids is 0.
Y
Yu Yang 已提交
417 418

    Args:
419 420 421 422 423 424
        input(Variable): A Tensor or LoDTensor with type int64, which contains the id information.
            The last dimension of Tensor shape must be equal to 1. The value of the input id should
            satisfy :math:`0<= id < size[0]` .
        size(tuple|list): The shape of lookup table parameter. It should have two elements which
            indicates the size of the dictionary of embeddings and the size of each embedding vector respectively.
        is_sparse(bool): The flag indicating whether to use sparse update. This parameter only
425
            affects the performance of the backwards gradient update. It is recommended to set
426
            True because sparse update is faster. But some optimizer does not support sparse update,
427
            such as :ref:`api_fluid_optimizer_AdadeltaOptimizer` , :ref:`api_fluid_optimizer_AdamaxOptimizer` ,
428 429 430 431 432
            :ref:`api_fluid_optimizer_DecayedAdagradOptimizer` , :ref:`api_fluid_optimizer_FtrlOptimizer` ,
            :ref:`api_fluid_optimizer_LambOptimizer` and :ref:`api_fluid_optimizer_LarsMomentumOptimizer` .
            In these case, is_sparse must be False. Default: False.
        is_distributed(bool): Whether to store the embedding matrix in a distributed manner. Only used
            in multi-machine distributed CPU training. Default: False.
433
        padding_idx(int|long|None): padding_idx needs to be in the interval [-vocab_size, vocab_size).
434 435 436 437 438 439
            If :math:`padding\_idx < 0`, the :math:`padding\_idx` will automatically be converted
            to :math:`vocab\_size + padding\_idx` . It will output all-zero padding data whenever lookup
            encounters :math:`padding\_idx` in id. And the padding data will not be updated while training.
            If set None, it makes no effect to output. Default: None.
        param_attr(ParamAttr): To specify the weight parameter property. Default: None, which means the
            default weight parameter property is used. See usage for details in :ref:`api_fluid_ParamAttr` . In addition,
440
            user-defined or pre-trained word vectors can be loaded with the :attr:`param_attr` parameter.
441
            The local word vector needs to be transformed into numpy format, and the shape of local word
T
tianshuo78520a 已提交
442
            vector should be consistent with :attr:`size` . Then :ref:`api_fluid_initializer_NumpyArrayInitializer`
443 444 445
            is used to load custom or pre-trained word vectors. See code example 2 for details.
        dtype(str|core.VarDesc.VarType): It refers to the data type of output Tensor.
            It must be float32 or float64. Default: float32.
Y
Yu Yang 已提交
446

447
    Returns:
448
        Variable: Embedding Tensor or LoDTensor mapped by input. The data type is the same as :attr:`dtype` .
Y
Yu Yang 已提交
449

450 451
    Examples:
        .. code-block:: python
Y
Yu Yang 已提交
452

B
bdzhuxiaoning 已提交
453
          import paddle.fluid as fluid
454
          import numpy as np
455 456
          import paddle
          paddle.enable_static()
457

458 459
          data = fluid.data(name='x', shape=[None, 1], dtype='int64')

T
tianshuo78520a 已提交
460
          # example 1
461 462 463 464 465 466 467 468 469
          emb_1 = fluid.embedding(input=data, size=[128, 64])

          # example 2: load custom or pre-trained word vectors
          weight_data = np.random.random(size=(128, 100))  # word vectors with numpy format
          w_param_attrs = fluid.ParamAttr(
              name="emb_weight",
              learning_rate=0.5,
              initializer=fluid.initializer.NumpyArrayInitializer(weight_data),
              trainable=True)
470
          emb_2 = fluid.layers.embedding(input=data, size=(128, 100), param_attr=w_param_attrs, dtype='float32')
Y
Yu Yang 已提交
471 472 473
    """

    helper = LayerHelper('embedding', **locals())
474 475 476 477 478 479 480 481 482
    check_variable_and_dtype(
        input, 'input', ['int64'], 'fluid.layers.embedding'
    )
    check_dtype(
        dtype,
        'dtype',
        ['uint16', 'float16', 'float32', 'float64'],
        'fluid.layers.embedding',
    )
483 484 485 486 487 488 489 490 491

    if is_distributed:
        is_distributed = False
        warnings.warn(
            "is_distributed is go out of use, `fluid.contrib.layers.sparse_embedding` is your needed"
        )

    remote_prefetch = True if is_sparse else False

492 493 494
    w = helper.create_parameter(
        attr=helper.param_attr, shape=size, dtype=dtype, is_bias=False
    )
X
Xin Pan 已提交
495
    tmp = helper.create_variable_for_type_inference(dtype)
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
    padding_idx = (
        -1
        if padding_idx is None
        else padding_idx
        if padding_idx >= 0
        else (size[0] + padding_idx)
    )
    helper.append_op(
        type='lookup_table',
        inputs={'Ids': input, 'W': w},
        outputs={'Out': tmp},
        attrs={
            'is_sparse': is_sparse,
            'is_distributed': is_distributed,
            'remote_prefetch': remote_prefetch,
            'padding_idx': padding_idx,
        },
    )
Y
Yu Yang 已提交
514 515 516
    return tmp


517 518 519 520 521 522 523 524 525 526 527
def _pull_sparse(
    input,
    size,
    table_id,
    accessor_class,
    name="embedding",
    ctr_label_name="",
    padding_id=0,
    dtype='float32',
    scale_sparse_grad=True,
):
528
    r"""
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
    **Pull Fleet Sparse Layer**

    This layer is used to lookup embeddings of IDs, provided by :attr:`input`, in
    Fleet lookup table. The result of this lookup is the embedding of each ID in the
    :attr:`input`.

    Args:
        input(Variable|list of Variable): Input is a Tensor<int64> Variable, which
            contains the IDs information.
        size(int): The embedding size parameter, which indicates the size of
            each embedding vector respectively.
        table_id(int): the fleet table id of this embedding.
        accessor_class(str): the pslib accessor of the table, default is DownpourCtrAccessor.
        ctr_label_name(str): the layer name of click.
        padding_id(int): the padding id during lookup, default is 0.
        dtype(str): The dtype refers to the data type of output tensor. Only supports
            float32 now.
        scale_sparse_grad(bool): whether to scale sparse gradient with batch size. default
            is True.

    Returns:
        Variable|list of Variable: The tensor variable storing the embeddings of the \
                  supplied inputs.

    Examples:
        .. code-block:: python

          import paddle.fluid as fluid
          data = fluid.layers.data(name='sequence', shape=[1], dtype='int64', lod_level=1)
          emb = fluid.layers.nn._pull_sparse(
              input=data, size=11, table_id=0, accessor_class="DownpourCtrAccessor")
    """
    helper = LayerHelper(name, **locals())
    inputs = helper.multiple_input()
    outs = [helper.create_variable_for_type_inference(dtype)]
    input_names = [i.name for i in inputs]
    attrs = {
        'EmbeddingDim': size,
        'TableId': table_id,
        'AccessorClass': accessor_class,
        'CtrLabelName': ctr_label_name,
        'PaddingId': padding_id,
        'ScaleSparseGrad': scale_sparse_grad,
        'InputNames': input_names,
        # this is only for compatible with embedding op
574
        'is_distributed': True,
575 576
    }
    # this is only for compatible with embedding op
577 578 579 580 581 582 583 584 585
    w, _ = helper.create_or_get_global_variable(
        name=name, shape=[size], dtype=dtype, is_bias=False, persistable=True
    )
    helper.append_op(
        type='pull_sparse',
        inputs={'Ids': inputs, 'W': w},
        outputs={'Out': outs},
        attrs=attrs,
    )
586 587 588 589 590
    if len(outs) == 1:
        return outs[0]
    return outs


591 592 593 594 595 596 597 598 599 600 601
def _pull_sparse_v2(
    input,
    size,
    table_id,
    accessor_class,
    name="embedding",
    ctr_label_name="",
    padding_id=0,
    dtype='float32',
    scale_sparse_grad=True,
):
602
    r"""
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
    **Pull Fleet Sparse Layer**

    This layer is used to lookup embeddings of IDs, provided by :attr:`input`, in
    Fleet lookup table. The result of this lookup is the embedding of each ID in the
    :attr:`input`.

    Args:
        input(Variable|list of Variable): Input is a Tensor<int64> Variable, which
            contains the IDs information.
        size(int): The embedding size parameter, which indicates the size of
            each embedding vector respectively.
        table_id(int): the pslib table id of this embedding.
        accessor_class(str): the fleet accessor of the table, default is DownpourCtrAccessor.
        ctr_label_name(str): the layer name of click.
        padding_id(int): the padding id during lookup, default is 0.
        dtype(str): The dtype refers to the data type of output tensor. Only supports
            float32 now.
        scale_sparse_grad(bool): whether to scale sparse gradient with batch size. default
            is True.

    Returns:
        Variable|list of Variable: The tensor variable storing the embeddings of the \
                  supplied inputs.

    Examples:
        .. code-block:: python

          import paddle.fluid as fluid
          data = fluid.layers.data(name='sequence', shape=[1], dtype='int64', lod_level=1)
          emb = fluid.layers.nn._pull_sparse_v2(
              input=data, size=11, table_id=0, accessor_class="DownpourCtrAccessor")
    """
    helper = LayerHelper(name, **locals())
    inputs = helper.multiple_input()
    outs = [helper.create_variable_for_type_inference(dtype)]
    input_names = [i.name for i in inputs]
    attrs = {
        'EmbeddingDim': size,
        'TableId': table_id,
        'AccessorClass': accessor_class,
        'CtrLabelName': ctr_label_name,
        'PaddingId': padding_id,
        'ScaleSparseGrad': scale_sparse_grad,
        'InputNames': input_names,
        # this is only for compatible with embedding op
648
        'is_distributed': True,
649 650
    }
    # this is only for compatible with embedding op
651 652 653 654 655 656 657 658 659
    w, _ = helper.create_or_get_global_variable(
        name=name, shape=[size], dtype=dtype, is_bias=False, persistable=True
    )
    helper.append_op(
        type='pull_sparse_v2',
        inputs={'Ids': inputs, 'W': w},
        outputs={'Out': outs},
        attrs=attrs,
    )
660
    if len(outs) == 1:
Y
yaoxuefeng 已提交
661 662 663 664
        return outs[0]
    return outs


665 666 667
def _pull_gpups_sparse(
    input, size, dtype='float32', is_distributed=False, is_sparse=False
):
Y
yaoxuefeng 已提交
668 669 670 671 672 673 674 675 676 677 678 679 680
    r"""
    **Pull GpuPS Sparse Layer**

    This layer is used to lookup embeddings of IDs, provided by :attr:`input`, in
    GpuPS lookup table. The result of this lookup is the embedding of each ID in the
    :attr:`input`.

    Args:
        input(Variable|list of Variable): Input is a Tensor<int64> Variable, which
            contains the IDs information.
        size(int|list of int): The embedding size parameter of each input, which indicates the size of
            each embedding vector respectively.
        dtype(str): The dtype refers to the data type of output tensor. Only supports
681
        float32 now.
Y
yaoxuefeng 已提交
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700

    Returns:
        Variable|list of Variable: The tensor variable storing the embeddings of the \
                  supplied inputs, whose size are indicated by size respectively.

    Examples:
        .. code-block:: python

          import paddle.fluid as fluid
          slots = []
          data_1 = fluid.layers.data(name='sequence', shape=[1], dtype='int64', lod_level=1)
          slots.append(data_1)
          data_2 = fluid.layers.data(name='sequence', shape=[1], dtype='int64', lod_level=1)
          slots.append(data_2)
          embs = fluid.layers.pull_gpups_sparse(input=slots, size=[11, 35])
    """
    helper = LayerHelper('pull_gpups_sparse', **locals())
    if dtype != 'float32':
        raise ValueError(
701 702 703
            "GpuPS only support float type embedding now, and your type is: "
            + dtype
        )
Y
yaoxuefeng 已提交
704 705 706 707 708 709
    helper.input_dtype()
    inputs = helper.multiple_input()
    outs = [
        helper.create_variable_for_type_inference(dtype)
        for i in range(len(inputs))
    ]
710 711 712 713 714 715 716 717 718 719 720 721 722
    w = helper.create_parameter(
        attr=helper.param_attr, shape=[size[0]], dtype=dtype, is_bias=False
    )
    helper.append_op(
        type='pull_gpups_sparse',
        inputs={'Ids': inputs, 'W': w},
        outputs={'Out': outs},
        attrs={
            'size': size,
            'is_distributed': is_distributed,
            'is_sparse': is_sparse,
        },
    )
Y
yaoxuefeng 已提交
723
    if len(outs) == 1:
724 725 726 727
        return outs[0]
    return outs


728 729 730
def _pull_box_sparse(
    input, size, dtype='float32', is_distributed=False, is_sparse=False
):
731
    r"""
H
hutuxian 已提交
732 733 734 735 736 737 738
    **Pull Box Sparse Layer**

    This layer is used to lookup embeddings of IDs, provided by :attr:`input`, in
    BoxPS lookup table. The result of this lookup is the embedding of each ID in the
    :attr:`input`.

    Args:
739
        input(Variable|list of Variable): Input is a Tensor<int64> Variable, which
H
hutuxian 已提交
740
            contains the IDs information.
741
        size(int): The embedding size parameter, which indicates the size of
H
hutuxian 已提交
742
            each embedding vector respectively.
743
        dtype(str): The dtype refers to the data type of output tensor. Only supports
744
        float32 now.
H
hutuxian 已提交
745 746 747 748 749 750 751 752 753 754

    Returns:
        Variable|list of Variable: The tensor variable storing the embeddings of the \
                  supplied inputs.

    Examples:
        .. code-block:: python

          import paddle.fluid as fluid
          data = fluid.layers.data(name='sequence', shape=[1], dtype='int64', lod_level=1)
755
          emb = fluid.layers.pull_box_sparse(input=data, size=[11])
H
hutuxian 已提交
756 757 758 759
    """
    helper = LayerHelper('pull_box_sparse', **locals())
    if dtype != 'float32':
        raise ValueError(
760 761 762
            "BoxPS only support float type embedding now, and your type is: "
            + dtype
        )
H
hutuxian 已提交
763 764 765 766 767 768
    helper.input_dtype()
    inputs = helper.multiple_input()
    outs = [
        helper.create_variable_for_type_inference(dtype)
        for i in range(len(inputs))
    ]
769 770 771 772 773 774 775 776 777 778 779 780 781
    w = helper.create_parameter(
        attr=helper.param_attr, shape=[size], dtype=dtype, is_bias=False
    )
    helper.append_op(
        type='pull_box_sparse',
        inputs={'Ids': inputs, 'W': w},
        outputs={'Out': outs},
        attrs={
            'size': size,
            'is_distributed': is_distributed,
            'is_sparse': is_sparse,
        },
    )
H
hutuxian 已提交
782 783 784 785 786
    if len(outs) == 1:
        return outs[0]
    return outs


Y
yuyang18 已提交
787
@templatedoc()
788
def linear_chain_crf(input, label, param_attr=None, length=None):
Y
yuyang18 已提交
789
    """
790 791
    :api_attr: Static Graph

Y
yuyang18 已提交
792 793 794 795 796
    Linear Chain CRF.

    ${comment}

    Args:
797
        input(${emission_type}): ${emission_comment}
Y
yuyang18 已提交
798
        label(${label_type}): ${label_comment}
799
        Length(${length_type}): ${length_comment}
800
        param_attr(ParamAttr): The attribute of the learnable parameter for transition parameter.
Y
yuyang18 已提交
801 802

    Returns:
D
dzhwinter 已提交
803 804
        output(${emission_exps_type}): ${emission_exps_comment} \n
        output(${transition_exps_type}): ${transition_exps_comment} \n
805
        output(${log_likelihood_type}): ${log_likelihood_comment} \n
Y
yuyang18 已提交
806

J
JesseyXujin 已提交
807 808 809
    Examples:
        .. code-block:: python

810 811
            import paddle.fluid as fluid
            import numpy as np
812 813
            import paddle
            paddle.enable_static()
814 815 816 817 818

            #define net structure, using LodTensor
            train_program = fluid.Program()
            startup_program = fluid.Program()
            with fluid.program_guard(train_program, startup_program):
819 820
                input_data = fluid.data(name='input_data', shape=[-1,10], dtype='float32')
                label = fluid.data(name='label', shape=[-1,1], dtype='int')
821 822 823 824 825 826
                emission= fluid.layers.fc(input=input_data, size=10, act="tanh")
                crf_cost = fluid.layers.linear_chain_crf(
                    input=emission,
                    label=label,
                    param_attr=fluid.ParamAttr(
                    name='crfw',
827
                    learning_rate=0.01))
828 829 830
            use_cuda = False
            place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
            exe = fluid.Executor(place)
831
            exe.run(startup_program)
832 833 834 835 836
            #define data, using LoDTensor
            a = fluid.create_lod_tensor(np.random.rand(12,10).astype('float32'), [[3,3,4,2]], place)
            b = fluid.create_lod_tensor(np.array([[1],[1],[2],[3],[1],[1],[1],[3],[1],[1],[1],[1]]),[[3,3,4,2]] , place)
            feed1 = {'input_data':a,'label':b}
            loss= exe.run(train_program,feed=feed1, fetch_list=[crf_cost])
837
            print(loss)
838 839 840 841 842

            #define net structure, using padding
            train_program = fluid.Program()
            startup_program = fluid.Program()
            with fluid.program_guard(train_program, startup_program):
843 844 845
                input_data2 = fluid.data(name='input_data2', shape=[-1,10,10], dtype='float32')
                label2 = fluid.data(name='label2', shape=[-1,10,1], dtype='int')
                label_length = fluid.data(name='length', shape=[-1,1], dtype='int')
846 847 848 849 850 851
                emission2= fluid.layers.fc(input=input_data2, size=10, act="tanh", num_flatten_dims=2)
                crf_cost2 = fluid.layers.linear_chain_crf(
                    input=emission2,
                    label=label2,
                    length=label_length,
                    param_attr=fluid.ParamAttr(
J
JesseyXujin 已提交
852
                     name='crfw',
853 854 855 856 857 858
                     learning_rate=0.01))

            use_cuda = False
            place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(startup_program)
J
JesseyXujin 已提交
859

860 861 862
            #define data, using padding
            cc=np.random.rand(4,10,10).astype('float32')
            dd=np.random.rand(4,10,1).astype('int64')
863
            ll=np.array([[3],[3],[4],[2]])
864 865
            feed2 = {'input_data2':cc,'label2':dd,'length':ll}
            loss2= exe.run(train_program,feed=feed2, fetch_list=[crf_cost2])
866
            print(loss2)
867 868 869 870 871
            #[array([[ 7.8902354],
            #        [ 7.3602567],
            #        [ 10.004011],
            #        [ 5.86721  ]], dtype=float32)]

872 873 874
            #you can use find_var to get transition parameter.
            transition=np.array(fluid.global_scope().find_var('crfw').get_tensor())
            print(transition)
875

Y
yuyang18 已提交
876
    """
877 878 879
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'linear_chain_crf'
    )
880
    check_variable_and_dtype(label, 'label', ['int64'], 'linear_chain_crf')
Y
Yu Yang 已提交
881
    helper = LayerHelper('linear_chain_crf', **locals())
882
    size = input.shape[2] if length else input.shape[1]
883 884 885 886 887
    transition = helper.create_parameter(
        attr=helper.param_attr,
        shape=[size + 2, size],
        dtype=helper.input_dtype(),
    )
X
Xin Pan 已提交
888
    alpha = helper.create_variable_for_type_inference(
889 890
        dtype=helper.input_dtype()
    )
X
Xin Pan 已提交
891
    emission_exps = helper.create_variable_for_type_inference(
892 893
        dtype=helper.input_dtype()
    )
X
Xin Pan 已提交
894
    transition_exps = helper.create_variable_for_type_inference(
895 896
        dtype=helper.input_dtype()
    )
X
Xin Pan 已提交
897
    log_likelihood = helper.create_variable_for_type_inference(
898 899
        dtype=helper.input_dtype()
    )
900 901 902
    this_inputs = {
        "Emission": [input],
        "Transition": transition,
903
        "Label": [label],
904 905
    }
    if length:
906
        this_inputs['Length'] = [length]
907 908 909 910 911 912 913 914 915 916
    helper.append_op(
        type='linear_chain_crf',
        inputs=this_inputs,
        outputs={
            "Alpha": [alpha],
            "EmissionExps": [emission_exps],
            "TransitionExps": transition_exps,
            "LogLikelihood": log_likelihood,
        },
    )
Y
Yu Yang 已提交
917 918 919 920

    return log_likelihood


W
wopeizl 已提交
921
@templatedoc()
922
def crf_decoding(input, param_attr, label=None, length=None):
W
wopeizl 已提交
923
    """
924
    :api_attr: Static Graph
925

W
wopeizl 已提交
926
    ${comment}
Y
yi.wu 已提交
927

W
wopeizl 已提交
928
    Args:
929
        input(Tensor): ${emission_comment}
Y
yi.wu 已提交
930

931 932
        param_attr (ParamAttr|None): To specify the weight parameter attribute.
            Default: None, which means the default weight parameter property is
933
            used. See usage for details in :ref:`api_paddle_fluid_param_attr_ParamAttr` .
Y
yuyang18 已提交
934

Y
Yibing Liu 已提交
935
        label(${label_type}, optional): ${label_comment}
936

Y
Yibing Liu 已提交
937
        length(${length_type}, optional): ${length_comment}
938

W
wopeizl 已提交
939
    Returns:
940
        Tensor: ${viterbi_path_comment}
Y
yi.wu 已提交
941

W
wopeizl 已提交
942 943
    Examples:
        .. code-block:: python
Y
yi.wu 已提交
944

945 946
           import paddle
           paddle.enable_static()
947 948 949

           # LoDTensor-based example
           num_labels = 10
950 951 952
           feature = paddle.static.data(name='word_emb', shape=[-1, 784], dtype='float32', lod_level=1)
           label = paddle.static.data(name='label', shape=[-1, 1], dtype='int64', lod_level=1)
           emission = paddle.static.nn.fc(feature, size=num_labels)
953

954 955 956 957
           crf_cost = paddle.fluid.layers.linear_chain_crf(input=emission, label=label,
                     param_attr=paddle.ParamAttr(name="crfw"))
           crf_decode = paddle.static.nn.crf_decoding(input=emission,
                     param_attr=paddle.ParamAttr(name="crfw"))
958 959 960

           # Common tensor example
           num_labels, max_len = 10, 20
961 962 963 964
           feature = paddle.static.data(name='word_emb_pad', shape=[-1, max_len, 784], dtype='float32')
           label = paddle.static.data(name='label_pad', shape=[-1, max_len, 1], dtype='int64')
           length = paddle.static.data(name='length', shape=[-1, 1], dtype='int64')
           emission = paddle.static.nn.fc(feature, size=num_labels,
965
                                      num_flatten_dims=2)
966

967 968 969 970
           crf_cost = paddle.fluid.layers.linear_chain_crf(input=emission, label=label, length=length,
                     param_attr=paddle.ParamAttr(name="crfw_pad"))
           crf_decode = paddle.static.nn.crf_decoding(input=emission, length=length,
                     param_attr=paddle.ParamAttr(name="crfw_pad"))
W
wopeizl 已提交
971
    """
972 973 974
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'crf_decoding'
    )
W
wopeizl 已提交
975 976 977
    helper = LayerHelper('crf_decoding', **locals())
    transition = helper.get_parameter(param_attr.name)
    viterbi_path = helper.create_variable_for_type_inference(
978 979
        dtype=core.VarDesc.VarType.INT64
    )
980 981 982
    inputs = {"Emission": [input], "Transition": transition, "Label": label}
    if length:
        inputs['Length'] = length
983 984 985 986 987
    helper.append_op(
        type='crf_decoding',
        inputs=inputs,
        outputs={"ViterbiPath": [viterbi_path]},
    )
Y
Yu Yang 已提交
988

W
wopeizl 已提交
989
    return viterbi_path
Y
Yu Yang 已提交
990 991


992
@deprecated(since="2.0.0", update_to="paddle.nn.functional.dropout")
993 994 995 996 997 998 999 1000
def dropout(
    x,
    dropout_prob,
    is_test=None,
    seed=None,
    name=None,
    dropout_implementation="downgrade_in_infer",
):
1001
    """
1002

1003 1004 1005 1006
    Computes dropout.

    Drop or keep each element of `x` independently. Dropout is a regularization
    technique for reducing overfitting by preventing neuron co-adaption during
1007
    training. The dropout operator randomly sets (according to the given dropout
1008 1009 1010
    probability) the outputs of some units to zero, while others are remain
    unchanged.

H
haowang101779990 已提交
1011 1012
    dropout op can be removed from the program to make the program more efficient.

1013
    Args:
L
lvmengsi 已提交
1014
        x (Variable): The input tensor variable. The data type is float16 or float32 or float64.
1015
        dropout_prob (float): Probability of setting units to zero.
1016
        is_test (bool): A flag indicating whether it is in test phrase or not.
1017
                        Default None, in dynamic graph, it use global tracer mode; in static graph, it means False.
1018 1019 1020
        seed (int): A Python integer used to create random seeds. If this
                    parameter is set to None, a random seed is used.
                    NOTE: If an integer seed is given, always the same output
L
lvmengsi 已提交
1021
                    units will be dropped. DO NOT use a fixed seed in training.Default: None.
1022 1023
        name (str|None): A name for this layer(optional). If set None, the layer
                         will be named automatically.
H
haowang101779990 已提交
1024 1025
        dropout_implementation(string): ['downgrade_in_infer'(default)|'upscale_in_train']

P
phlrain 已提交
1026
                                        1. downgrade_in_infer(default), downgrade the outcome at inference
H
haowang101779990 已提交
1027 1028

                                           - train: out = input * mask
C
ceci3 已提交
1029
                                           - inference: out = input * (1.0 - dropout_prob)
H
haowang101779990 已提交
1030 1031 1032

                                           (mask is a tensor same shape with input, value is 0 or 1
                                           ratio of 0 is dropout_prob)
P
phlrain 已提交
1033
                                        2. upscale_in_train, upscale the outcome at training time
1034

H
haowang101779990 已提交
1035 1036
                                           - train: out = input * mask / ( 1.0 - dropout_prob )
                                           - inference: out = input
P
phlrain 已提交
1037

H
haowang101779990 已提交
1038 1039
                                           (mask is a tensor same shape with input, value is 0 or 1
                                           ratio of 0 is dropout_prob)
1040

M
minqiyang 已提交
1041

1042
    Returns:
L
lvmengsi 已提交
1043
        A Variable holding Tensor representing the dropout, has same shape and data type with `x`.
1044 1045

    Examples:
1046

1047 1048
        .. code-block:: python

1049
            import paddle
1050
            import paddle.fluid as fluid
1051

1052
            paddle.enable_static()
L
lvmengsi 已提交
1053
            x = fluid.data(name="data", shape=[None, 32, 32], dtype="float32")
T
tianshuo78520a 已提交
1054
            dropped = fluid.layers.dropout(x, dropout_prob=0.5)
1055
    """
1056 1057
    if not isinstance(dropout_prob, (float, int, Variable)):
        raise TypeError(
1058 1059
            "dropout_prob argument should be a number(int|float) or Variable"
        )
1060
    # fast return for p == 0
1061
    if isinstance(dropout_prob, (int, float)) and dropout_prob == 0:
1062
        return x
1063

J
Jiabin Yang 已提交
1064
    if _non_static_mode():
1065 1066 1067
        if (
            seed is None or seed == 0
        ) and default_main_program().random_seed != 0:
1068
            seed = default_main_program().random_seed
1069 1070
        if is_test is None:
            is_test = not _dygraph_tracer()._train_mode
1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083
        out, mask = _legacy_C_ops.dropout(
            x,
            'dropout_prob',
            dropout_prob,
            'is_test',
            is_test,
            'fix_seed',
            seed is not None,
            'seed',
            seed if seed is not None else 0,
            'dropout_implementation',
            dropout_implementation,
        )
1084
        return out
1085

W
wanghuancoder 已提交
1086 1087 1088
    def get_attrs(prog, dropout_prob, is_test, seed):
        if (seed is None or seed == 0) and prog.random_seed != 0:
            seed = prog.random_seed
1089 1090
        if isinstance(dropout_prob, Variable) and not dropout_prob.shape != [1]:
            raise TypeError(
1091 1092 1093 1094
                "Required dropout_prob.shape == [1] if type(dropout_prob) is Variable, but received dropout_prob.shape = {}".format(
                    dropout_prob.shape
                )
            )
W
wanghuancoder 已提交
1095 1096 1097 1098 1099 1100 1101 1102 1103
        attrs = {
            'dropout_prob': dropout_prob,
            'is_test': is_test,
            'fix_seed': seed is not None,
            'seed': seed if seed is not None else 0,
            'dropout_implementation': dropout_implementation,
        }
        return attrs

F
fengjiayi 已提交
1104
    helper = LayerHelper('dropout', **locals())
1105 1106 1107
    check_variable_and_dtype(
        x, 'x', ['float16', 'float32', 'float64'], 'dropout'
    )
1108

X
Xin Pan 已提交
1109 1110
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
    mask = helper.create_variable_for_type_inference(
1111 1112
        dtype=core.VarDesc.VarType.UINT8, stop_gradient=True
    )
C
chengduo 已提交
1113

1114
    attrs = get_attrs(helper.main_program, dropout_prob, is_test, seed)
C
chengduo 已提交
1115

1116 1117 1118 1119 1120 1121
    helper.append_op(
        type='dropout',
        inputs={'X': [x]},
        outputs={'Out': [out], 'Mask': [mask]},
        attrs=attrs,
    )
1122 1123 1124
    return out


1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139
def conv2d(
    input,
    num_filters,
    filter_size,
    stride=1,
    padding=0,
    dilation=1,
    groups=None,
    param_attr=None,
    bias_attr=None,
    use_cudnn=True,
    act=None,
    name=None,
    data_format="NCHW",
):
1140
    r"""
1141 1142
    :api_attr: Static Graph

C
chengduoZH 已提交
1143
    The convolution2D layer calculates the output based on the input, filter
T
tensor-tang 已提交
1144
    and strides, paddings, dilations, groups parameters. Input and
L
liym27 已提交
1145
    Output are in NCHW or NHWC format, where N is batch size, C is the number of
1146
    channels, H is the height of the feature, and W is the width of the feature.
T
tensor-tang 已提交
1147 1148 1149 1150 1151 1152
    Filter is in MCHW format, where M is the number of output image channels,
    C is the number of input image channels, H is the height of the filter,
    and W is the width of the filter. If the groups is greater than 1,
    C will equal the number of input image channels divided by the groups.
    Please refer to UFLDL's `convolution
    <http://ufldl.stanford.edu/tutorial/supervised/FeatureExtractionUsingConvolution/>`_
1153
    for more details.
1154 1155 1156
    If bias attribution and activation type are provided, bias is added to the
    output of the convolution, and the corresponding activation function is
    applied to the final result.
C
chengduoZH 已提交
1157

1158
    For each input :math:`X`, the equation is:
C
refine  
chengduoZH 已提交
1159

C
chengduoZH 已提交
1160 1161
    .. math::

C
refine  
chengduoZH 已提交
1162
        Out = \sigma (W \\ast X + b)
C
chengduoZH 已提交
1163

T
tensor-tang 已提交
1164
    Where:
C
chengduoZH 已提交
1165

L
liym27 已提交
1166
    * :math:`X`: Input value, a tensor with NCHW or NHWC format.
1167 1168 1169 1170
    * :math:`W`: Filter value, a tensor with MCHW format.
    * :math:`\\ast`: Convolution operation.
    * :math:`b`: Bias value, a 2-D tensor with shape [M, 1].
    * :math:`\\sigma`: Activation function.
T
tensor-tang 已提交
1171
    * :math:`Out`: Output value, the shape of :math:`Out` and :math:`X` may be different.
C
chengduoZH 已提交
1172 1173 1174

    Example:

1175 1176
        - Input:

W
weixing02 已提交
1177
          Input shape: :math:`(N, C_{in}, H_{in}, W_{in})`
C
refine  
chengduoZH 已提交
1178

W
weixing02 已提交
1179
          Filter shape: :math:`(C_{out}, C_{in}, H_f, W_f)`
C
refine  
chengduoZH 已提交
1180

1181
        - Output:
T
tensor-tang 已提交
1182

W
weixing02 已提交
1183
          Output shape: :math:`(N, C_{out}, H_{out}, W_{out})`
C
refine  
chengduoZH 已提交
1184

C
chengduoZH 已提交
1185
        Where
1186 1187

        .. math::
C
chengduoZH 已提交
1188

W
weixing02 已提交
1189 1190
            H_{out}&= \\frac{(H_{in} + 2 * paddings[0] - (dilations[0] * (H_f - 1) + 1))}{strides[0]} + 1 \\\\
            W_{out}&= \\frac{(W_{in} + 2 * paddings[1] - (dilations[1] * (W_f - 1) + 1))}{strides[1]} + 1
C
chengduoZH 已提交
1191 1192

    Args:
1193
        input (Tensor): The input is 4-D Tensor with shape [N, C, H, W], the data type
L
lvmengsi 已提交
1194
            of input is float16 or float32 or float64.
T
tensor-tang 已提交
1195
        num_filters(int): The number of filter. It is as same as the output
1196
            image channel.
1197 1198
        filter_size (int|tuple): The filter size. If filter_size
            is a tuple, it must contain two integers, (filter_size_height,
L
lvmengsi 已提交
1199 1200
            filter_size_width). Otherwise, filter_size_height = filter_size_width =\
            filter_size.
1201 1202
        stride (int|tuple): The stride size. It means the stride in convolution.
            If stride is a tuple, it must contain two integers, (stride_height, stride_width).
L
lvmengsi 已提交
1203 1204
            Otherwise, stride_height = stride_width = stride. Default: stride = 1.
        padding (string|int|list|tuple): The padding size. It means the number of zero-paddings
T
tianshuo78520a 已提交
1205
            on both sides for each dimension.If `padding` is a string, either 'VALID' or
L
liym27 已提交
1206 1207
            'SAME' which is the padding algorithm. If padding size is a tuple or list,
            it could be in three forms: `[pad_height, pad_width]` or
1208 1209
            `[pad_height_top, pad_height_bottom, pad_width_left, pad_width_right]`, and when
            `data_format` is `"NCHW"`, `padding` can be in the form `[[0,0], [0,0],
L
lvmengsi 已提交
1210
            [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right]]`.
L
liym27 已提交
1211 1212 1213
            when `data_format` is `"NHWC"`, `pool_padding` can be in the form
            `[[0,0], [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right], [0,0]]`.
            Default: padding = 0.
L
lvmengsi 已提交
1214
        dilation (int|tuple): The dilation size. It means the spacing between the kernel
1215 1216
            points. If dilation is a tuple, it must contain two integers, (dilation_height,
            dilation_width). Otherwise, dilation_height = dilation_width = dilation.
L
lvmengsi 已提交
1217
            Default: dilation = 1.
1218 1219 1220 1221
        groups (int): The groups number of the Conv2d Layer. According to grouped
            convolution in Alex Krizhevsky's Deep CNN paper: when group=2,
            the first half of the filters is only connected to the first half
            of the input channels, while the second half of the filters is only
C
chengduo 已提交
1222 1223 1224 1225 1226
            connected to the second half of the input channels. Default: groups=1.
        param_attr (ParamAttr|None): The parameter attribute for learnable parameters/weights
            of conv2d. If it is set to None or one attribute of ParamAttr, conv2d
            will create ParamAttr as param_attr. If the Initializer of the param_attr
            is not set, the parameter is initialized with :math:`Normal(0.0, std)`,
H
haowang101779990 已提交
1227
            and the :math:`std` is :math:`(\\frac{2.0 }{filter\_elem\_num})^{0.5}`. Default: None.
C
chengduo 已提交
1228 1229 1230 1231 1232
        bias_attr (ParamAttr|bool|None): The parameter attribute for the bias of conv2d.
            If it is set to False, no bias will be added to the output units.
            If it is set to None or one attribute of ParamAttr, conv2d
            will create ParamAttr as bias_attr. If the Initializer of the bias_attr
            is not set, the bias is initialized zero. Default: None.
1233 1234
        use_cudnn (bool): Use cudnn kernel or not, it is valid only when the cudnn
            library is installed. Default: True
C
chengduo 已提交
1235 1236
        act (str): Activation type, if it is set to None, activation is not appended.
            Default: None
1237 1238
        name(str|None): For detailed information, please refer
           to :ref:`api_guide_Name`. Usually name is no need to set and
L
lvmengsi 已提交
1239
           None by default.
1240
        data_format (str, optional): Specify the data format of the input, and the data format of the output
1241
            will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`.
L
liym27 已提交
1242 1243
            The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
            `[batch_size, input_channels, input_height, input_width]`.
C
chengduoZH 已提交
1244 1245

    Returns:
1246 1247 1248
        A Tensor representing the conv2d, whose data type is the
        same with input. If act is None, the tensor storing the convolution
        result, and if act is not None, the tensor storing convolution
L
lvmengsi 已提交
1249
        and non-linearity activation result.
C
refine  
chengduoZH 已提交
1250

1251 1252 1253 1254 1255
    Raises:
        ValueError: If the type of `use_cudnn` is not bool.
        ValueError: If `data_format` is not "NCHW" or "NHWC".
        ValueError: If the channel dimmention of the input is less than or equal to zero.
        ValueError: If `padding` is a string, but not "SAME" or "VALID".
1256
        ValueError: If `padding` is a tuple, but the element corresponding to the input's batch size is not 0
1257 1258 1259 1260 1261 1262 1263
            or the element corresponding to the input's channel is not 0.
        ShapeError: If the input is not 4-D Tensor.
        ShapeError: If the input's dimension size and filter's dimension size not equal.
        ShapeError: If the dimension size of input minus the size of `stride` is not 2.
        ShapeError: If the number of input channels is not equal to filter's channels * groups.
        ShapeError: If the number of output channels is not be divided by groups.

C
chengduoZH 已提交
1264 1265 1266
    Examples:
        .. code-block:: python

1267 1268
          import paddle
          paddle.enable_static()
1269

1270 1271 1272
          data = paddle.static.data(name='data', shape=[None, 3, 32, 32], dtype='float32')
          conv2d = paddle.static.nn.conv2d(input=data, num_filters=2, filter_size=3, act="relu")
          print(conv2d.shape) # [-1, 2, 30, 30]
Y
Yu Yang 已提交
1273 1274
    """

1275 1276 1277
    check_variable_and_dtype(
        input, 'input', ['float16', 'float32', 'float64'], 'conv2d'
    )
1278
    if len(input.shape) != 4:
1279 1280 1281 1282
        raise ValueError(
            "Input size should be 4, "
            "but received {}".format(len(input.shape))
        )
1283
    num_channels = input.shape[1]
L
liym27 已提交
1284
    if not isinstance(use_cudnn, bool):
1285 1286 1287 1288
        raise ValueError(
            "Attr(use_cudnn) should be True or False. Received "
            "Attr(use_cudnn): %s. " % str(use_cudnn)
        )
L
liym27 已提交
1289 1290 1291 1292

    if data_format not in ["NCHW", "NHWC"]:
        raise ValueError(
            "Attr(data_format) should be 'NCHW' or 'NHWC'. Received "
1293 1294
            "Attr(data_format): %s." % str(data_format)
        )
L
liym27 已提交
1295

1296
    channel_last = data_format == "NHWC"
L
liym27 已提交
1297 1298 1299 1300
    num_channels = input.shape[3] if channel_last else input.shape[1]
    if num_channels < 0:
        raise ValueError(
            "The channel dimmention of the input(%s) should be defined. "
1301 1302
            "Received: %s." % (str(input.shape), str(num_channels))
        )
C
chengduo 已提交
1303
    assert param_attr is not False, "param_attr should not be False here."
L
liym27 已提交
1304

1305 1306 1307
    if groups is None:
        num_filter_channels = num_channels
    elif groups <= 0:
1308 1309
        raise ValueError(
            "the groups of input must be greater than 0, "
1310 1311
            "but received the groups of input is {}".format(groups)
        )
1312 1313 1314 1315 1316
    else:
        if num_channels % groups != 0:
            raise ValueError(
                "the channel of input must be divisible by groups,"
                "received: the channel of input is {}, the shape of input is {}"
1317 1318
                ", the groups is {}".format(num_channels, input.shape, groups)
            )
1319 1320
        num_filter_channels = num_channels // groups

1321
    l_type = 'conv2d'
1322 1323 1324 1325 1326
    if (
        num_channels == groups
        and num_filters % num_channels == 0
        and not use_cudnn
    ):
1327
        l_type = 'depthwise_conv2d'
1328

1329 1330 1331 1332 1333
    if (
        num_channels == groups
        and num_filters % num_channels == 0
        and core.is_compiled_with_rocm()
    ):
1334 1335
        l_type = 'depthwise_conv2d'

1336 1337
    # NPU only supports depthwise_conv2d when  "input_channel = output_channel = groups"
    if core.is_compiled_with_npu():
1338
        if num_channels == groups and num_channels == num_filters:
1339 1340 1341 1342
            l_type = 'depthwise_conv2d'
        else:
            l_type = 'conv2d'

1343 1344 1345
    helper = LayerHelper(l_type, **locals())
    dtype = helper.input_dtype()

C
chengduoZH 已提交
1346 1347
    filter_size = utils.convert_to_list(filter_size, 2, 'filter_size')
    stride = utils.convert_to_list(stride, 2, 'stride')
1348
    dilation = utils.convert_to_list(dilation, 2, 'dilation')
C
chengduoZH 已提交
1349

L
liym27 已提交
1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361
    # padding
    def _update_padding(padding, data_format):
        def is_list_or_tuple(ele):
            if isinstance(ele, list) or isinstance(ele, tuple):
                return True
            return False

        if is_list_or_tuple(padding) and len(padding) == 4:
            if is_list_or_tuple(padding[0]) and (data_format == "NCHW"):
                if not (padding[0] == [0, 0] and padding[1] == [0, 0]):
                    raise ValueError(
                        "Non-zero padding(%s) in the batch or channel dimensions "
1362 1363
                        "is not supported." % str(padding)
                    )
L
liym27 已提交
1364 1365 1366 1367 1368 1369
                padding = padding[2:4]
                padding = [ele for a_list in padding for ele in a_list]
            elif is_list_or_tuple(padding[0]) and (data_format == "NHWC"):
                if not (padding[0] == [0, 0] and padding[3] == [0, 0]):
                    raise ValueError(
                        "Non-zero padding(%s) in the batch or channel dimensions "
1370 1371
                        "is not supported." % str(padding)
                    )
L
liym27 已提交
1372 1373 1374
                padding = padding[1:3]
                padding = [ele for a_list in padding for ele in a_list]
            padding = utils.convert_to_list(padding, 4, 'padding')
1375 1376 1377
            if utils._is_symmetric_padding(padding, 2):
                padding = [padding[0], padding[2]]

L
liym27 已提交
1378 1379 1380 1381 1382 1383 1384 1385 1386 1387
        else:
            padding = utils.convert_to_list(padding, 2, 'padding')

        return padding

    padding_algorithm = "EXPLICIT"
    if isinstance(padding, str):
        padding = padding.upper()
        if padding not in ["SAME", "VALID"]:
            raise ValueError(
1388 1389 1390
                "Unknown padding: '%s'. It can only be 'SAME' or 'VALID'."
                % str(padding)
            )
L
liym27 已提交
1391 1392
        if padding == "VALID":
            padding_algorithm = "VALID"
1393
            padding = [0, 0]
L
liym27 已提交
1394 1395
        elif padding == "SAME":
            padding_algorithm = "SAME"
1396
            padding = [0, 0]
L
liym27 已提交
1397 1398

    padding = _update_padding(padding, data_format)
Y
Yu Yang 已提交
1399

M
minqiyang 已提交
1400
    filter_shape = [num_filters, int(num_filter_channels)] + filter_size
Y
Yu Yang 已提交
1401 1402

    def _get_default_param_initializer():
C
chengduo 已提交
1403
        filter_elem_num = filter_size[0] * filter_size[1] * num_channels
1404 1405 1406 1407
        if filter_elem_num <= 0:
            raise ValueError(
                "Invalid filter number, excepted number is larger than 0, but"
                " received {}, please check the input shape and "
1408 1409 1410
                "filter size.".format(filter_elem_num)
            )
        std = (2.0 / filter_elem_num) ** 0.5
Y
Yu Yang 已提交
1411 1412 1413 1414 1415 1416
        return Normal(0.0, std, 0)

    filter_param = helper.create_parameter(
        attr=helper.param_attr,
        shape=filter_shape,
        dtype=dtype,
1417 1418
        default_initializer=_get_default_param_initializer(),
    )
Y
Yu Yang 已提交
1419

X
Xin Pan 已提交
1420
    pre_bias = helper.create_variable_for_type_inference(dtype)
Y
Yu Yang 已提交
1421

1422 1423 1424 1425 1426 1427
    if (
        core.is_compiled_with_cuda()
        and paddle.fluid.get_flags("FLAGS_conv2d_disable_cudnn")[
            "FLAGS_conv2d_disable_cudnn"
        ]
    ):
1428 1429
        use_cudnn = False

1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448
    helper.append_op(
        type=l_type,
        inputs={
            'Input': input,
            'Filter': filter_param,
        },
        outputs={"Output": pre_bias},
        attrs={
            'strides': stride,
            'paddings': padding,
            'dilations': dilation,
            'groups': groups,
            'use_cudnn': use_cudnn,
            'use_mkldnn': False,
            'fuse_relu_before_depthwise_conv': False,
            "padding_algorithm": padding_algorithm,
            "data_format": data_format,
        },
    )
Y
Yu Yang 已提交
1449

1450 1451 1452 1453
    if data_format == 'NCHW':
        pre_act = helper.append_bias_op(pre_bias, dim_start=1, dim_end=2)
    else:
        pre_act = helper.append_bias_op(pre_bias, dim_start=3, dim_end=4)
Y
Yu Yang 已提交
1454 1455 1456 1457

    return helper.append_activation(pre_act)


F
fengjiayi 已提交
1458
@templatedoc()
1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471
def pool2d(
    input,
    pool_size=-1,
    pool_type="max",
    pool_stride=1,
    pool_padding=0,
    global_pooling=False,
    use_cudnn=True,
    ceil_mode=False,
    name=None,
    exclusive=True,
    data_format="NCHW",
):
Y
Yu Yang 已提交
1472
    """
1473

F
fengjiayi 已提交
1474
    ${comment}
1475 1476

    Args:
K
Kaipeng Deng 已提交
1477 1478 1479 1480 1481
        input (Variable): The input tensor of pooling operator which is a 4-D tensor with
                          shape [N, C, H, W]. The format of input tensor is `"NCHW"` or
                          `"NHWC"`, where `N` is batch size, `C` is the number of channels,
                          `H` is the height of the feature, and `W` is the width of the
                          feature. The data type if float32 or float64.
J
JiabinYang 已提交
1482
        pool_size (int|list|tuple): The pool kernel size. If pool kernel size is a tuple or list,
J
JiabinYang 已提交
1483 1484
            it must contain two integers, (pool_size_Height, pool_size_Width).
            Otherwise, the pool kernel size will be a square of an int.
F
fengjiayi 已提交
1485
        pool_type: ${pooling_type_comment}
J
JiabinYang 已提交
1486 1487 1488
        pool_stride (int|list|tuple): The pool stride size. If pool stride size is a tuple or list,
            it must contain two integers, (pool_stride_Height, pool_stride_Width).
            Otherwise, the pool stride size will be a square of an int.
1489 1490 1491 1492 1493 1494 1495
        pool_padding (string|int|list|tuple): The pool padding. If `pool_padding` is a string, either 'VALID' or
            'SAME' which is the padding algorithm. If pool padding size is a tuple or list,
            it could be in three forms: `[pad_height, pad_width]` or
            `[pad_height_top, pad_height_bottom, pad_width_left, pad_width_right]`, and when `data_format` is `"NCHW"`,
            `pool_padding` can be in the form `[[0,0], [0,0], [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right]]`.
            when `data_format` is `"NHWC"`, `pool_padding` can be in the form
            `[[0,0], [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right], [0,0]]`.
J
JiabinYang 已提交
1496
            Otherwise, the pool padding size will be a square of an int.
1497 1498 1499
        global_pooling (bool): ${global_pooling_comment}
        use_cudnn (bool): ${use_cudnn_comment}
        ceil_mode (bool): ${ceil_mode_comment}
K
Kaipeng Deng 已提交
1500 1501 1502
        name(str, optional): For detailed information, please refer
                             to :ref:`api_guide_Name`. Usually name is no need to set and
                             None by default.
1503
        exclusive (bool): Whether to exclude padding points in average pooling
1504
                          mode, default is `true`.
1505
        data_format (string): The data format of the input and output data. An optional string from: `"NCHW"`, `"NHWC"`.
1506 1507
                The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
                `[batch_size, input_channels, input_height, input_width]`.
F
fengjiayi 已提交
1508

1509
    Returns:
K
Kaipeng Deng 已提交
1510
        Variable: The output tensor of pooling result. The data type is same as input tensor.
F
fengjiayi 已提交
1511 1512

    Raises:
1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524
        ValueError: If `pool_type` is not "max" nor "avg".
        ValueError: If `global_pooling` is False and `pool_size` is -1.
        TypeError: If `use_cudnn` is not a bool value.
        ValueError: If `data_format` is not "NCHW" or "NHWC".
        ValueError: If `pool_padding` is a string, but not "SAME" or "VALID".
        ValueError: If `pool_padding` is "VALID", but `ceil_mode` is True.
        ValueError: If `pool_padding` is a list or tuple, but the elements in the batch or channel dimensions are non-zero.
        ShapeError: If the input is not a 4-D or 5-D Tensor.
        ShapeError: If the dimension of input minus the size of `pool_stride` is not 2.
        ShapeError: If the size of `pool_size` and `pool_stride` is not equal.
        ShapeError: If the output's shape calculated is not greater than 0.

F
fengjiayi 已提交
1525 1526 1527 1528 1529

    Examples:

        .. code-block:: python

1530
          import paddle.fluid as fluid
1531 1532 1533
          import paddle

          paddle.enable_static()
1534

K
Kaipeng Deng 已提交
1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559
          data = fluid.data(name='data', shape=[None, 3, 32, 32], dtype='float32')

          # max pool2d
          pool2d = fluid.layers.pool2d(
            input = data,
            pool_size = 2,
            pool_type = "max",
            pool_stride = 1,
            global_pooling=False)

          # average pool2d
          pool2d = fluid.layers.pool2d(
            input = data,
            pool_size = 2,
            pool_type = "avg",
            pool_stride = 1,
            global_pooling=False)

          # global average pool2d
          pool2d = fluid.layers.pool2d(
            input = data,
            pool_size = 2,
            pool_type = "avg",
            pool_stride = 1,
            global_pooling=True)
1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577

          # Attr(pool_padding) is a list with 4 elements, Attr(data_format) is "NCHW".
          out_1 = fluid.layers.pool2d(
            input = data,
            pool_size = 3,
            pool_type = "avg",
            pool_stride = 1,
            pool_padding = [1, 2, 1, 0],
            data_format = "NCHW")

          # Attr(pool_padding) is a string, Attr(data_format) is "NCHW".
          out_2 = fluid.layers.pool2d(
            input = data,
            pool_size = 3,
            pool_type = "avg",
            pool_stride = 1,
            pool_padding = "VALID",
            data_format = "NCHW")
Y
Yu Yang 已提交
1578 1579 1580
    """
    if pool_type not in ["max", "avg"]:
        raise ValueError(
1581
            "Unknown Attr(pool_type): '%s'. It can only be 'max' or 'avg'.",
1582 1583
            str(pool_type),
        )
C
chengduoZH 已提交
1584

C
chengduoZH 已提交
1585 1586
    if global_pooling is False and pool_size == -1:
        raise ValueError(
1587
            "When Attr(global_pooling) is False, Attr(pool_size) must be passed "
1588 1589
            "and be a valid value. Received pool_size: %s." % str(pool_size)
        )
1590 1591

    if not isinstance(use_cudnn, bool):
1592 1593 1594 1595
        raise TypeError(
            "Attr(use_cudnn) should be True or False. Received "
            "Attr(use_cudnn): %s." % str(use_cudnn)
        )
1596 1597 1598 1599

    if data_format not in ["NCHW", "NHWC"]:
        raise ValueError(
            "Attr(data_format) should be 'NCHW' or 'NHWC'. Received "
1600 1601
            "Attr(data_format): %s." % str(data_format)
        )
C
chengduoZH 已提交
1602

C
chengduoZH 已提交
1603 1604 1605
    pool_size = utils.convert_to_list(pool_size, 2, 'pool_size')
    pool_stride = utils.convert_to_list(pool_stride, 2, 'pool_stride')

1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616
    def update_padding(padding, data_format):
        def is_list_or_tuple(ele):
            if isinstance(ele, list) or isinstance(ele, tuple):
                return True
            return False

        if is_list_or_tuple(padding) and len(padding) == 4:
            if is_list_or_tuple(padding[0]) and (data_format == "NCHW"):
                if not (padding[0] == [0, 0] and padding[1] == [0, 0]):
                    raise ValueError(
                        "Non-zero pool_padding(%s) in the batch or channel dimensions "
1617 1618
                        "is not supported." % str(padding)
                    )
1619 1620 1621 1622 1623 1624
                padding = padding[2:4]
                padding = [ele for a_list in padding for ele in a_list]
            elif is_list_or_tuple(padding[0]) and (data_format == "NHWC"):
                if not (padding[0] == [0, 0] and padding[3] == [0, 0]):
                    raise ValueError(
                        "Non-zero pool_padding(%s) in the batch or channel dimensions "
1625 1626
                        "is not supported." % str(padding)
                    )
1627 1628 1629
                padding = padding[1:3]
                padding = [ele for a_list in padding for ele in a_list]
            padding = utils.convert_to_list(padding, 4, 'padding')
1630

1631 1632
            if utils._is_symmetric_padding(padding, 2):
                padding = [padding[0], padding[2]]
1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643
        else:
            padding = utils.convert_to_list(padding, 2, 'padding')

        return padding

    padding_algorithm = "EXPLICIT"
    if isinstance(pool_padding, str):
        pool_padding = pool_padding.upper()
        if pool_padding not in ["SAME", "VALID"]:
            raise ValueError(
                "Unknown Attr(pool_padding): '%s'. It can only be 'SAME' or 'VALID'."
1644 1645
                % str(pool_padding)
            )
1646 1647
        if pool_padding == "VALID":
            padding_algorithm = "VALID"
1648
            pool_padding = [0, 0]
1649
            if ceil_mode is not False:
1650 1651
                raise ValueError(
                    "When Attr(pool_padding) is \"VALID\", Attr(ceil_mode) must be False. "
1652 1653
                    "Received ceil_mode: True."
                )
1654 1655
        elif pool_padding == "SAME":
            padding_algorithm = "SAME"
1656
            pool_padding = [0, 0]
1657 1658

    pool_padding = update_padding(pool_padding, data_format)
1659
    if in_dygraph_mode():
1660
        input = input._use_gpudnn(use_cudnn)
1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673
        return _C_ops.pool2d(
            input,
            pool_size,
            pool_stride,
            pool_padding,
            ceil_mode,
            exclusive,
            data_format,
            pool_type,
            global_pooling,
            False,
            padding_algorithm,
        )
1674 1675
    op_type = 'pool2d'
    helper = LayerHelper(op_type, **locals())
Y
Yu Yang 已提交
1676
    dtype = helper.input_dtype()
X
Xin Pan 已提交
1677
    pool_out = helper.create_variable_for_type_inference(dtype)
Y
Yu Yang 已提交
1678

1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696
    helper.append_op(
        type=op_type,
        inputs={"X": input},
        outputs={"Out": pool_out},
        attrs={
            "pooling_type": pool_type,
            "ksize": pool_size,
            "global_pooling": global_pooling,
            "strides": pool_stride,
            "paddings": pool_padding,
            "padding_algorithm": padding_algorithm,
            "use_cudnn": use_cudnn,
            "ceil_mode": ceil_mode,
            "use_mkldnn": False,
            "exclusive": exclusive,
            "data_format": data_format,
        },
    )
1697 1698 1699 1700

    return pool_out


1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716
def batch_norm(
    input,
    act=None,
    is_test=False,
    momentum=0.9,
    epsilon=1e-05,
    param_attr=None,
    bias_attr=None,
    data_layout='NCHW',
    in_place=False,
    name=None,
    moving_mean_name=None,
    moving_variance_name=None,
    do_model_average_for_mean_and_var=True,
    use_global_stats=False,
):
1717
    r"""
1718 1719
    :api_attr: Static Graph

Q
qiaolongfei 已提交
1720 1721
    **Batch Normalization Layer**

L
lvmengsi 已提交
1722
    Can be used as a normalizer function for convolution or fully_connected operations.
Q
qiaolongfei 已提交
1723
    The required data format for this layer is one of the following:
Q
qiaolongfei 已提交
1724

Q
qiaolongfei 已提交
1725
    1. NHWC `[batch, in_height, in_width, in_channels]`
Q
qiaolongfei 已提交
1726

Q
qiaolongfei 已提交
1727 1728
    2. NCHW `[batch, in_channels, in_height, in_width]`

Q
qiaolongfei 已提交
1729 1730 1731
    Refer to `Batch Normalization: Accelerating Deep Network Training by Reducing
    Internal Covariate Shift <https://arxiv.org/pdf/1502.03167.pdf>`_
    for more details.
Q
qiaolongfei 已提交
1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743

    :math:`input` is the input features over a mini-batch.

    ..  math::

        \\mu_{\\beta} &\\gets \\frac{1}{m} \\sum_{i=1}^{m} x_i \\qquad &//\\
        \ mini-batch\ mean \\\\
        \\sigma_{\\beta}^{2} &\\gets \\frac{1}{m} \\sum_{i=1}^{m}(x_i - \\
        \\mu_{\\beta})^2 \\qquad &//\ mini-batch\ variance \\\\
        \\hat{x_i} &\\gets \\frac{x_i - \\mu_\\beta} {\\sqrt{\\
        \\sigma_{\\beta}^{2} + \\epsilon}} \\qquad &//\ normalize \\\\
        y_i &\\gets \\gamma \\hat{x_i} + \\beta \\qquad &//\ scale\ and\ shift
1744

L
lvmengsi 已提交
1745
        moving\_mean = moving\_mean * momentum + mini-batch\_mean * (1. - momentum) \\\\
1746
        moving\_var = moving\_var * momentum + mini-batch\_var * (1. - momentum)
L
lvmengsi 已提交
1747

1748

L
lvmengsi 已提交
1749
    moving_mean is global mean and moving_var is global variance.
1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762

    When use_global_stats = True, the :math:`\\mu_{\\beta}`
    and :math:`\\sigma_{\\beta}^{2}` are not the statistics of one mini-batch.
    They are global (or running) statistics. (It usually got from the
    pre-trained model.)
    The training and testing (or inference) have the same behavior:

    ..  math::

        \\hat{x_i} &\\gets \\frac{x_i - \\mu_\\beta} {\\sqrt{\\
        \\sigma_{\\beta}^{2} + \\epsilon}}  \\\\
        y_i &\\gets \\gamma \\hat{x_i} + \\beta

L
lvmengsi 已提交
1763
    Note:
1764
        if build_strategy.sync_batch_norm=True, the batch_norm in network will use
L
lvmengsi 已提交
1765
        sync_batch_norm automatically.
1766
        `is_test = True` can only be used in test program and inference program, `is_test` CANNOT be set to True in train program, if you want to use global status from pre_train model in train program, please set `use_global_stats = True`.
L
lvmengsi 已提交
1767

1768
    Args:
1769
        input(Tensor): The rank of input Tensor can be 2, 3, 4, 5. The data type
L
lvmengsi 已提交
1770
            is float16 or float32 or float64.
Q
qiaolongfei 已提交
1771
        act(string, Default None): Activation type, linear|relu|prelu|...
Q
qingqing01 已提交
1772 1773
        is_test (bool, Default False): A flag indicating whether it is in
            test phrase or not.
1774 1775
        momentum(float|Tensor, Default 0.9): The value used for the moving_mean and
            moving_var computation. This should be a float number or a Tensor with
1776
            shape [1] and data type as float32. The updated formula is:
Q
qingqing01 已提交
1777 1778 1779 1780 1781
            :math:`moving\_mean = moving\_mean * momentum + new\_mean * (1. - momentum)`
            :math:`moving\_var = moving\_var * momentum + new\_var * (1. - momentum)`
            Default is 0.9.
        epsilon(float, Default 1e-05): A value added to the denominator for
            numerical stability. Default is 1e-5.
C
chengduo 已提交
1782 1783
        param_attr(ParamAttr|None): The parameter attribute for Parameter `scale`
             of batch_norm. If it is set to None or one attribute of ParamAttr, batch_norm
1784
	     will create ParamAttr as param_attr, the name of scale can be set in ParamAttr.
1785
	     If the Initializer of the param_attr is not set, the parameter is initialized
1786
	     with Xavier. Default: None.
C
chengduo 已提交
1787 1788
        bias_attr(ParamAttr|None): The parameter attribute for the bias of batch_norm.
             If it is set to None or one attribute of ParamAttr, batch_norm
1789 1790
	     will create ParamAttr as bias_attr, the name of bias can be set in ParamAttr.
	     If the Initializer of the bias_attr is not set, the bias is initialized zero.
1791
	     Default: None.
1792
        data_layout (str, optional): Specify the data format of the input, and the data format of the output
K
Kaipeng Deng 已提交
1793 1794 1795
             will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`.
             The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
             `[batch_size, input_channels, input_height, input_width]`.
1796
        in_place(bool, Default False): Make the input and output of batch norm reuse memory.
1797 1798 1799 1800
        name(str|None): For detailed information, please refer to :ref:`api_guide_Name`.
            Usually name is no need to set and None by default.
        moving_mean_name(str, Default None): The name of moving_mean which store the global Mean. If it
            is set to None, batch_norm will save global mean with a random name, otherwise, batch_norm
1801
            will save global mean with the string.
L
lvmengsi 已提交
1802
        moving_variance_name(str, Default None): The name of the moving_variance which store the global Variance.
1803
            If it is set to None, batch_norm will save global variance with a random name, otherwise, batch_norm
1804
            will save global variance with the string.
1805 1806
        do_model_average_for_mean_and_var(bool, Default True): Whether parameter mean and variance should do model
            average when model average is enabled.
1807 1808 1809 1810 1811
        use_global_stats(bool, Default False): Whether to use global mean and
            variance. In inference or test mode, set use_global_stats to true
            or is_test to true, and the behavior is equivalent.
            In train mode, when setting use_global_stats True, the global mean
            and variance are also used during train period.
1812
    Returns:
1813
        A Tensor which is the result after applying batch normalization on the input,
1814
        has same shape and data type with input.
Q
qiaolongfei 已提交
1815 1816 1817 1818 1819

    Examples:

        .. code-block:: python

1820
            import paddle
1821

1822
            paddle.enable_static()
1823 1824 1825 1826 1827 1828 1829
            x = paddle.static.data(name='x', shape=[3, 7, 3, 7], dtype='float32')
            hidden1 = paddle.static.nn.fc(x=x, size=200)
            print(hidden1.shape)
            # [3, 200]
            hidden2 = paddle.static.nn.batch_norm(input=hidden1)
            print(hidden2.shape)
            # [3, 200]
Y
Yu Yang 已提交
1830
    """
1831 1832 1833
    assert (
        bias_attr is not False
    ), "bias_attr should not be False in batch_norm."
Y
Yu Yang 已提交
1834 1835
    helper = LayerHelper('batch_norm', **locals())

1836 1837 1838
    check_variable_and_dtype(
        input, 'input', ['float16', 'float32', 'float64'], 'batch_norm'
    )
1839
    dtype = helper.input_dtype()
1840

W
Wu Yi 已提交
1841 1842 1843 1844
    # use fp32 for bn parameter
    if dtype == core.VarDesc.VarType.FP16:
        dtype = core.VarDesc.VarType.FP32

Y
Yu Yang 已提交
1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856
    input_shape = input.shape
    if data_layout == 'NCHW':
        channel_num = input_shape[1]
    else:
        if data_layout == 'NHWC':
            channel_num = input_shape[-1]
        else:
            raise ValueError("unsupported data layout:" + data_layout)

    param_shape = [channel_num]

    # create parameter
1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876
    scale = helper.create_parameter(
        attr=helper.param_attr,
        shape=param_shape,
        dtype=dtype,
        default_initializer=Constant(1.0),
    )
    bias = helper.create_parameter(
        attr=helper.bias_attr, shape=param_shape, dtype=dtype, is_bias=True
    )

    mean = helper.create_parameter(
        attr=ParamAttr(
            name=moving_mean_name,
            initializer=Constant(0.0),
            trainable=False,
            do_model_average=do_model_average_for_mean_and_var,
        ),
        shape=param_shape,
        dtype=dtype,
    )
1877 1878
    mean.stop_gradient = True

1879 1880 1881 1882 1883 1884 1885 1886 1887 1888
    variance = helper.create_parameter(
        attr=ParamAttr(
            name=moving_variance_name,
            initializer=Constant(1.0),
            trainable=False,
            do_model_average=do_model_average_for_mean_and_var,
        ),
        shape=param_shape,
        dtype=dtype,
    )
1889
    variance.stop_gradient = True
Y
Yu Yang 已提交
1890 1891 1892 1893

    # create output
    # mean and mean_out share the same memory
    mean_out = mean
1894
    # variance and variance_out share the same memory
Y
Yu Yang 已提交
1895
    variance_out = variance
1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907

    if in_dygraph_mode():
        inputs_has_MomemtumTensor = False
        attrs_has_momentum = False
        tmp_tensor_type = core.eager.Tensor
        if isinstance(momentum, tmp_tensor_type):
            inputs_has_MomemtumTensor = True
        else:
            attrs_has_momentum = True

        attrs_ = ()
        if attrs_has_momentum:
1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923
            attrs_ = (
                'momentum',
                momentum,
                'epsilon',
                epsilon,
                'is_test',
                is_test,
                'data_layout',
                data_layout,
                'use_mkldnn',
                False,
                'fuse_with_relu',
                False,
                'use_global_stats',
                use_global_stats,
            )
1924
        else:
1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938
            attrs_ = (
                'epsilon',
                epsilon,
                'is_test',
                is_test,
                'data_layout',
                data_layout,
                'use_mkldnn',
                False,
                'fuse_with_relu',
                False,
                'use_global_stats',
                use_global_stats,
            )
1939
        if inputs_has_MomemtumTensor:
1940
            batch_norm_out, _, _, _, _, _ = _legacy_C_ops.batch_norm(
1941 1942 1943 1944 1945 1946 1947 1948 1949 1950
                input,
                scale,
                bias,
                mean,
                variance,
                momentum,
                mean_out,
                variance_out,
                *attrs_,
            )
1951
        else:
1952
            batch_norm_out, _, _, _, _, _ = _legacy_C_ops.batch_norm(
1953 1954 1955 1956 1957 1958 1959 1960 1961 1962
                input,
                scale,
                bias,
                mean,
                variance,
                None,
                mean_out,
                variance_out,
                *attrs_,
            )
1963

1964 1965 1966
        return dygraph_utils._append_activation_in_dygraph(
            batch_norm_out, act=act, use_mkldnn=False
        )
1967

1968 1969 1970
    saved_mean = helper.create_variable_for_type_inference(
        dtype=dtype, stop_gradient=True
    )
X
Xin Pan 已提交
1971
    saved_variance = helper.create_variable_for_type_inference(
1972 1973
        dtype=dtype, stop_gradient=True
    )
1974
    reserve_space = None
1975
    if not is_test:
1976
        reserve_space = helper.create_variable_for_type_inference(
1977 1978
            dtype=helper.input_dtype(), stop_gradient=True
        )
1979

1980 1981 1982
    batch_norm_out = (
        input if in_place else helper.create_variable_for_type_inference(dtype)
    )
Y
Yu Yang 已提交
1983

1984 1985 1986 1987 1988
    inputs = {
        "X": input,
        "Scale": scale,
        "Bias": bias,
        "Mean": mean,
1989 1990
        "Variance": variance,
        "MeanOut": mean_out,
1991
        "VarianceOut": variance_out,
1992 1993 1994 1995 1996 1997 1998
    }
    attrs = {
        "epsilon": epsilon,
        "is_test": is_test,
        "data_layout": data_layout,
        "use_mkldnn": False,
        "fuse_with_relu": False,
1999
        "use_global_stats": use_global_stats,
2000 2001 2002 2003 2004
    }
    if isinstance(momentum, Variable):
        inputs['MomemtumTensor'] = momentum
    else:
        attrs['momentum'] = momentum
2005 2006 2007 2008 2009 2010

    outputs = {
        "Y": batch_norm_out,
        "MeanOut": mean_out,
        "VarianceOut": variance_out,
        "SavedMean": saved_mean,
2011
        "SavedVariance": saved_variance,
2012 2013 2014 2015
    }
    if reserve_space is not None:
        outputs["ReserveSpace"] = reserve_space

2016 2017 2018
    helper.append_op(
        type="batch_norm", inputs=inputs, outputs=outputs, attrs=attrs
    )
Y
Yu Yang 已提交
2019 2020 2021 2022

    return helper.append_activation(batch_norm_out)


Y
yuyang18 已提交
2023
@templatedoc()
2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034
def layer_norm(
    input,
    scale=True,
    shift=True,
    begin_norm_axis=1,
    epsilon=1e-05,
    param_attr=None,
    bias_attr=None,
    act=None,
    name=None,
):
2035
    r"""
2036 2037
    :api_attr: Static Graph

2038 2039 2040 2041
    **Layer Normalization Layer**

    The API implements the function of the Layer Normalization Layer and can be applied to mini-batch input data.
    Refer to `Layer Normalization <https://arxiv.org/pdf/1607.06450v1.pdf>`_
G
guosheng 已提交
2042 2043 2044

    The formula is as follows:

Y
yuyang18 已提交
2045
    ..  math::
G
guosheng 已提交
2046

2047
        \\mu & = \\frac{1}{H}\\sum_{i=1}^{H} x_i
G
guosheng 已提交
2048

2049
        \\sigma & = \\sqrt{\\frac{1}{H}\sum_{i=1}^{H}{(x_i - \\mu)^2} + \\epsilon}
Y
yuyang18 已提交
2050

2051
        y & = f(\\frac{g}{\\sigma}(x - \\mu) + b)
Y
yuyang18 已提交
2052

2053 2054 2055 2056 2057
    - :math:`x`: the vector representation of the summed inputs to the neurons in that layer.
    - :math:`H`: the number of hidden units in a layers
    - :math:`\\epsilon`: the small value added to the variance to prevent division by zero.
    - :math:`g`: the trainable scale parameter.
    - :math:`b`: the trainable bias parameter.
Y
yuyang18 已提交
2058

G
guosheng 已提交
2059
    Args:
2060
        input(Tensor): A multi-dimension ``Tensor`` , and the data type is float32 or float64.
2061 2062 2063 2064 2065
        scale(bool, optional): Whether to learn the adaptive gain :math:`g` after
            normalization. Default: True.
        shift(bool, optional): Whether to learn the adaptive bias :math:`b` after
            normalization. Default: True.
        begin_norm_axis(int, optional): The normalization will be performed along
G
guosheng 已提交
2066
            dimensions from :attr:`begin_norm_axis` to :attr:`rank(input)`.
2067 2068 2069 2070
            Default: 1.
        epsilon(float, optional): The small value added to the variance to prevent
            division by zero. Default: 1e-05.
        param_attr(ParamAttr, optional): The parameter attribute for the learnable
S
sneaxiy 已提交
2071 2072
            gain :math:`g`. If :attr:`scale` is False, :attr:`param_attr` is
            omitted. If :attr:`scale` is True and :attr:`param_attr` is None,
2073
            a default :code:`ParamAttr` would be added as scale. The
2074 2075
            :attr:`param_attr` is initialized as 1 if it is added. Default: None.
        bias_attr(ParamAttr, optional): The parameter attribute for the learnable
S
sneaxiy 已提交
2076 2077
            bias :math:`b`. If :attr:`shift` is False, :attr:`bias_attr` is
            omitted. If :attr:`shift` is True and :attr:`param_attr` is None,
2078
            a default :code:`ParamAttr` would be added as bias. The
2079
            :attr:`bias_attr` is initialized as 0 if it is added. Default: None.
T
tianshuo78520a 已提交
2080
        act(str, optional): Activation to be applied to the output of layer normalization.
2081 2082
                  Default: None.
        name(str): The default value is None.  Normally there is no need for user to set this property.  For more information, please refer to :ref:`api_guide_Name` .
G
guosheng 已提交
2083 2084

    Returns:
2085
        Tensor: ``Tensor``  indicating the normalized result, the data type is the same as  ``input`` , and the return dimension is the same as  ``input`` .
G
guosheng 已提交
2086 2087 2088

    Examples:

2089 2090
        .. code-block:: python

2091 2092
            import paddle
            paddle.enable_static()
2093 2094 2095
            x = paddle.static.data(name='x', shape=[8, 32, 32], dtype='float32')
            output = paddle.static.nn.layer_norm(input=x, begin_norm_axis=1)
            print(output.shape)  # [8, 32, 32]
G
guosheng 已提交
2096
    """
2097 2098 2099
    assert (
        _non_static_mode() is not True
    ), "please use LayerNorm instead of layer_norm in dygraph mode!"
G
guosheng 已提交
2100
    helper = LayerHelper('layer_norm', **locals())
2101 2102 2103
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'layer_norm'
    )
G
guosheng 已提交
2104 2105 2106 2107 2108 2109 2110
    dtype = helper.input_dtype()

    # create intput and parameters
    inputs = {'X': input}
    input_shape = input.shape
    param_shape = [reduce(lambda x, y: x * y, input_shape[begin_norm_axis:])]
    if scale:
2111 2112 2113 2114 2115 2116 2117 2118 2119
        assert (
            param_attr is not False
        ), "param_attr should not be False when using scale."
        scale = helper.create_parameter(
            attr=helper.param_attr,
            shape=param_shape,
            dtype=dtype,
            default_initializer=Constant(1.0),
        )
G
guosheng 已提交
2120
        inputs['Scale'] = scale
2121 2122
    else:
        if param_attr:
T
tianshuo78520a 已提交
2123
            warnings.warn("param_attr is only available with scale is True.")
G
guosheng 已提交
2124
    if shift:
2125 2126 2127 2128 2129 2130
        assert (
            bias_attr is not False
        ), "bias_attr should not be False when using shift."
        bias = helper.create_parameter(
            attr=helper.bias_attr, shape=param_shape, dtype=dtype, is_bias=True
        )
G
guosheng 已提交
2131
        inputs['Bias'] = bias
2132 2133
    else:
        if bias_attr:
T
tianshuo78520a 已提交
2134
            warnings.warn("bias_attr is only available with shift is True.")
G
guosheng 已提交
2135 2136

    # create output
2137 2138 2139 2140 2141 2142
    mean_out = helper.create_variable_for_type_inference(
        dtype=dtype, stop_gradient=True
    )
    variance_out = helper.create_variable_for_type_inference(
        dtype=dtype, stop_gradient=True
    )
X
Xin Pan 已提交
2143
    layer_norm_out = helper.create_variable_for_type_inference(dtype)
G
guosheng 已提交
2144

2145 2146 2147 2148 2149 2150 2151 2152 2153 2154
    helper.append_op(
        type="layer_norm",
        inputs=inputs,
        outputs={
            "Y": layer_norm_out,
            "Mean": mean_out,
            "Variance": variance_out,
        },
        attrs={"epsilon": epsilon, "begin_norm_axis": begin_norm_axis},
    )
G
guosheng 已提交
2155 2156 2157 2158

    return helper.append_activation(layer_norm_out)


D
dengkaipeng 已提交
2159
@templatedoc()
2160
def spectral_norm(weight, dim=0, power_iters=1, eps=1e-12, name=None):
2161
    r"""
2162 2163
    :api_attr: Static Graph

D
dengkaipeng 已提交
2164 2165
    **Spectral Normalization Layer**

K
Kaipeng Deng 已提交
2166
    This operation calculates the spectral normalization value of weight parameters of
2167
    fc, conv1d, conv2d, conv3d layers which should be 2-D, 3-D, 4-D, 5-D
K
Kaipeng Deng 已提交
2168 2169
    Parameters. Output tensor will be in same shape with input tensor.
    Calculations are showed as follows.
2170

D
dengkaipeng 已提交
2171 2172 2173
    Step 1:
    Generate vector U in shape of [H], and V in shape of [W].
    While H is the :attr:`dim` th dimension of the input weights,
D
dengkaipeng 已提交
2174
    and W is the product result of remaining dimensions.
D
dengkaipeng 已提交
2175 2176

    Step 2:
T
tianshuo78520a 已提交
2177
    :attr:`power_iters` should be a positive integer, do following
K
Kaipeng Deng 已提交
2178 2179
    calculations with U and V for :attr:`power_iters` rounds. Calculations
    as follows:
D
dengkaipeng 已提交
2180

2181
    .. math::
D
dengkaipeng 已提交
2182 2183 2184 2185 2186 2187

        \mathbf{v} := \\frac{\mathbf{W}^{T} \mathbf{u}}{\|\mathbf{W}^{T} \mathbf{u}\|_2}

        \mathbf{u} := \\frac{\mathbf{W}^{T} \mathbf{v}}{\|\mathbf{W}^{T} \mathbf{v}\|_2}

    Step 3:
D
dengkaipeng 已提交
2188
    Calculate :math:`\sigma(\mathbf{W})` and normalize weight values.
D
dengkaipeng 已提交
2189 2190 2191 2192

    .. math::

        \sigma(\mathbf{W}) = \mathbf{u}^{T} \mathbf{W} \mathbf{v}
2193

D
dengkaipeng 已提交
2194
        \mathbf{W} = \\frac{\mathbf{W}}{\sigma(\mathbf{W})}
2195

2196

D
dengkaipeng 已提交
2197 2198 2199
    Refer to `Spectral Normalization <https://arxiv.org/abs/1802.05957>`_ .

    Args:
C
Chen Long 已提交
2200
        weight(Tensor): ${weight_comment}
D
dengkaipeng 已提交
2201 2202 2203
        dim(int): ${dim_comment}
        power_iters(int): ${power_iters_comment}
        eps(float): ${eps_comment}
K
Kaipeng Deng 已提交
2204 2205 2206
        name(str, optional): For detailed information, please refer
                             to :ref:`api_guide_Name`. Usually name is no need to set and
                             None by default.
D
dengkaipeng 已提交
2207 2208

    Returns:
C
Chen Long 已提交
2209
        Tensor: A tensor of weight parameters after spectral normalization.
K
Kaipeng Deng 已提交
2210
                  The data type and shape is same as input tensor.
D
dengkaipeng 已提交
2211 2212

    Examples:
K
Kaipeng Deng 已提交
2213
       .. code-block:: python
D
dengkaipeng 已提交
2214

2215
            import paddle
K
Kaipeng Deng 已提交
2216

2217
            paddle.enable_static()
C
Chen Long 已提交
2218
            weight = paddle.static.data(name='weight', shape=[2, 8, 32, 32], dtype='float32')
2219
            x = paddle.static.nn.spectral_norm(weight=weight, dim=1, power_iters=2)
C
Chen Long 已提交
2220
            print(x.shape) # [2, 8, 32, 32]
D
dengkaipeng 已提交
2221 2222
    """
    helper = LayerHelper('spectral_norm', **locals())
2223 2224 2225
    check_variable_and_dtype(
        weight, 'weight', ['float32', 'float64'], 'spectral_norm'
    )
2226 2227 2228
    check_type(dim, 'dim', int, 'spectral_norm')
    check_type(power_iters, 'power_iters', int, 'spectral_norm')
    check_type(eps, 'eps', float, 'spectral_norm')
2229
    dtype = weight.dtype
D
dengkaipeng 已提交
2230 2231

    # create intput and parameters
2232
    input_shape = weight.shape
2233
    assert weight.numel() > 0, "Any dimension of input cannot be equal to 0."
2234 2235 2236 2237 2238
    assert dim < len(input_shape), (
        "The input `dim` should be less than the "
        "rank of `weight`, but received dim="
        "{}".format(dim)
    )
2239 2240 2241
    h = input_shape[dim]
    w = np.prod(input_shape) // h

2242 2243 2244 2245 2246 2247
    u = helper.create_parameter(
        attr=ParamAttr(),
        shape=[h],
        dtype=dtype,
        default_initializer=Normal(0.0, 1.0),
    )
2248
    u.stop_gradient = True
2249 2250 2251 2252 2253 2254
    v = helper.create_parameter(
        attr=ParamAttr(),
        shape=[w],
        dtype=dtype,
        default_initializer=Normal(0.0, 1.0),
    )
2255
    v.stop_gradient = True
D
dengkaipeng 已提交
2256

2257 2258 2259 2260 2261 2262 2263
    if in_dygraph_mode():
        return _C_ops.spectral_norm(weight, u, v, dim, power_iters, eps)

    inputs = {'Weight': weight}
    inputs['U'] = u
    inputs['V'] = v

D
dengkaipeng 已提交
2264
    # create output
2265
    out = helper.create_variable(dtype=dtype)
D
Dun 已提交
2266

2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278
    helper.append_op(
        type="spectral_norm",
        inputs=inputs,
        outputs={
            "Out": out,
        },
        attrs={
            "dim": dim,
            "power_iters": power_iters,
            "eps": eps,
        },
    )
D
Dun 已提交
2279

2280
    return out
D
Dun 已提交
2281 2282


C
caoying03 已提交
2283
def reduce_sum(input, dim=None, keep_dim=False, name=None):
G
guosheng 已提交
2284
    """
2285

Y
yangyaming 已提交
2286
    Computes the sum of tensor elements over the given dimension.
G
guosheng 已提交
2287 2288

    Args:
2289 2290 2291
        input (Variable): The input variable which is a Tensor, the data type is float32,
            float64, int32, int64.
        dim (list|int, optional): The dimensions along which the sum is performed. If
Y
yangyaming 已提交
2292 2293
            :attr:`None`, sum all elements of :attr:`input` and return a
            Tensor variable with a single element, otherwise must be in the
W
whs 已提交
2294 2295
            range :math:`[-rank(input), rank(input))`. If :math:`dim[i] < 0`,
            the dimension to reduce is :math:`rank + dim[i]`.
2296
        keep_dim (bool, optional): Whether to reserve the reduced dimension in the
Y
yangyaming 已提交
2297
            output Tensor. The result tensor will have one fewer dimension
2298 2299 2300 2301
            than the :attr:`input` unless :attr:`keep_dim` is true, default
            value is False.
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`
G
guosheng 已提交
2302 2303

    Returns:
2304 2305
        Variable: Tensor, results of summation operation on the specified dim of input tensor,
        it's data type is the same as input's Tensor.
F
fengjiayi 已提交
2306

2307 2308
    Raises:
        TypeError, if out data type is different with the input data type.
2309

G
guosheng 已提交
2310 2311 2312
    Examples:
        .. code-block:: python

2313
            import paddle.fluid as fluid
2314 2315
            import paddle
            paddle.enable_static()
G
guosheng 已提交
2316 2317 2318
            # x is a Tensor variable with following elements:
            #    [[0.2, 0.3, 0.5, 0.9]
            #     [0.1, 0.2, 0.6, 0.7]]
Q
qiaolongfei 已提交
2319
            # Each example is followed by the corresponding output tensor.
2320
            x = fluid.data(name='x', shape=[2, 4], dtype='float32')
G
guosheng 已提交
2321 2322 2323 2324
            fluid.layers.reduce_sum(x)  # [3.5]
            fluid.layers.reduce_sum(x, dim=0)  # [0.3, 0.5, 1.1, 1.6]
            fluid.layers.reduce_sum(x, dim=-1)  # [1.9, 1.6]
            fluid.layers.reduce_sum(x, dim=1, keep_dim=True)  # [[1.9], [1.6]]
W
whs 已提交
2325

2326
            # y is a Tensor variable with shape [2, 2, 2] and elements as below:
W
whs 已提交
2327 2328
            #      [[[1, 2], [3, 4]],
            #      [[5, 6], [7, 8]]]
Q
qiaolongfei 已提交
2329
            # Each example is followed by the corresponding output tensor.
2330
            y = fluid.data(name='y', shape=[2, 2, 2], dtype='float32')
2331 2332
            fluid.layers.reduce_sum(y, dim=[1, 2]) # [10, 26]
            fluid.layers.reduce_sum(y, dim=[0, 1]) # [16, 20]
W
whs 已提交
2333

G
guosheng 已提交
2334
    """
2335 2336
    reduce_all, dim = _get_reduce_dim(dim, input)

2337
    if in_dygraph_mode():
2338
        return _C_ops.sum(input, dim, None, keep_dim)
2339
    elif _in_legacy_dygraph():
2340 2341 2342
        return _legacy_C_ops.reduce_sum(
            input, 'dim', dim, 'keep_dim', keep_dim, 'reduce_all', reduce_all
        )
2343
    attrs = {'dim': dim, 'keep_dim': keep_dim, 'reduce_all': reduce_all}
2344
    check_variable_and_dtype(
2345 2346 2347 2348 2349
        input,
        'input',
        ['float16', 'float32', 'float64', 'int32', 'int64'],
        'reduce_sum',
    )
2350
    helper = LayerHelper('reduce_sum', **locals())
X
Xin Pan 已提交
2351
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
2352 2353 2354 2355 2356 2357
    helper.append_op(
        type='reduce_sum',
        inputs={'X': input},
        outputs={'Out': out},
        attrs=attrs,
    )
G
guosheng 已提交
2358
    return out
G
guosheng 已提交
2359 2360


C
caoying03 已提交
2361
def split(input, num_or_sections, dim=-1, name=None):
G
guosheng 已提交
2362
    """
2363
    Split the input tensor into multiple sub-Tensors.
G
guosheng 已提交
2364 2365

    Args:
2366
        input (Tensor): A N-D Tensor. The data type is bool, float16, float32, float64, int32 or int64.
2367
        num_or_sections (int|list|tuple): If ``num_or_sections`` is int, then the ``num_or_sections``
2368
            indicates the number of equal sized sub-Tensors that the ``input``
2369
            will be divided into. If ``num_or_sections`` is a list or tuple, the length of it
2370 2371 2372 2373 2374
            indicates the number of sub-Tensors and the elements in it indicate the sizes of sub-Tensors'
            dimension orderly. The length of the list mustn't be larger than the ``input`` 's size of specified dim.
        dim (int|Tensor, optional): The dimension along which to split, it can be a scalar with type ``int`` or
            a ``Tensor`` with shape [1] and data type ``int32`` or ``int64``. If :math:`dim < 0`,
            the dimension to split along is :math:`rank(input) + dim`. Default is -1.
2375
        name (str, optional): The default value is None.  Normally there is no need for user to set this property.
2376
            For more information, please refer to :ref:`api_guide_Name` .
G
guosheng 已提交
2377 2378

    Returns:
2379
        list(Tensor): The list of segmented Tensors.
G
guosheng 已提交
2380

2381
    Example:
G
guosheng 已提交
2382 2383
        .. code-block:: python

2384 2385
            import paddle.fluid as fluid

2386
            # input is a Tensor which shape is [3, 9, 5]
2387
            input = fluid.data(
2388 2389
                 name="input", shape=[3, 9, 5], dtype="float32")

2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403
            out0, out1, out2 = fluid.layers.split(input, num_or_sections=3, dim=1)
            # out0.shape [3, 3, 5]
            # out1.shape [3, 3, 5]
            # out2.shape [3, 3, 5]

            out0, out1, out2 = fluid.layers.split(input, num_or_sections=[2, 3, 4], dim=1)
            # out0.shape [3, 2, 5]
            # out1.shape [3, 3, 5]
            # out2.shape [3, 4, 5]

            out0, out1, out2 = fluid.layers.split(input, num_or_sections=[2, 3, -1], dim=1)
            # out0.shape [3, 2, 5]
            # out1.shape [3, 3, 5]
            # out2.shape [3, 4, 5]
2404

2405 2406 2407 2408 2409 2410
            # dim is negative, the real dim is (rank(input) + axis) which real
            # value is 1.
            out0, out1, out2 = fluid.layers.split(input, num_or_sections=3, dim=-2)
            # out0.shape [3, 3, 5]
            # out1.shape [3, 3, 5]
            # out2.shape [3, 3, 5]
2411

G
guosheng 已提交
2412
    """
J
Jiabin Yang 已提交
2413
    if _non_static_mode():
2414 2415 2416
        num = None
        attrs = ()

S
songyouwei 已提交
2417 2418
        if isinstance(dim, Variable):
            dim = dim.numpy()
2419
            dim = dim.item(0)
W
wangzhen38 已提交
2420
        assert len(input.shape) + dim >= 0, "(rank(x) + axis) must >= 0"
S
songyouwei 已提交
2421
        dim = (len(input.shape) + dim) if dim < 0 else dim
2422
        attrs += ('axis', dim)
2423 2424 2425

        if isinstance(num_or_sections, int):
            num = num_or_sections
2426
            attrs += ('num', num_or_sections)
L
Leo Chen 已提交
2427
        elif isinstance(num_or_sections, (list, tuple)):
2428
            num = len(num_or_sections)
L
Leo Chen 已提交
2429
            if utils._contain_var(num_or_sections):
2430 2431
                for index, item in enumerate(num_or_sections):
                    if isinstance(item, Variable):
2432 2433 2434
                        num_or_sections[index] = num_or_sections[index].numpy()[
                            0
                        ]
2435
                attrs += ('sections', list(num_or_sections))
L
Leo Chen 已提交
2436
            else:
2437
                attrs += ('sections', list(num_or_sections))
2438 2439
        else:
            raise TypeError(
2440
                "The type of 'num_or_sections' in split must be int, list or tuple in imperative mode, but "
2441 2442
                "received %s." % (type(num_or_sections))
            )
2443
        if in_dygraph_mode():
C
Charles-hit 已提交
2444 2445 2446 2447
            if isinstance(num_or_sections, int):
                return _C_ops.split_with_num(input, num_or_sections, dim)
            else:
                return _C_ops.split(input, num_or_sections, dim)
2448 2449
        elif _in_legacy_dygraph():
            out = [_varbase_creator() for n in range(num)]
2450
            _legacy_C_ops.split(input, out, *attrs)
2451
            return out
L
Leo Chen 已提交
2452

2453
    check_variable_and_dtype(
2454 2455 2456 2457 2458
        input,
        'input',
        ['bool', 'float16', 'float32', 'float64', 'int32', 'int64'],
        'split',
    )
2459 2460 2461 2462
    check_type(num_or_sections, 'num_or_sections', (list, int, tuple), 'split')
    check_type(dim, 'dim', (int, Variable), 'split')
    if isinstance(dim, Variable):
        check_dtype(dim.dtype, 'dim', ['int32', 'int64'], 'split')
2463

G
guosheng 已提交
2464
    helper = LayerHelper('split', **locals())
2465

G
guosheng 已提交
2466
    input_shape = input.shape
2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477
    inputs = {'X': input}
    attrs = {'num': num_or_sections if isinstance(num_or_sections, int) else 0}

    def _get_SectionsTensorList(one_list):
        tensor_list = []
        unk_dim_idx = -1
        for idx, dim_size in enumerate(one_list):
            if isinstance(dim_size, Variable):
                dim_size.stop_gradient = True
                tensor_list.append(dim_size)
            else:
2478
                assert isinstance(dim_size, int)
2479 2480 2481
                if dim_size == -1:
                    assert unk_dim_idx == -1, (
                        "Only one value of 'num_or_section' in split can "
2482 2483 2484
                        "be -1. But received num_or_section[%d] is also -1."
                        % idx
                    )
2485 2486
                    unk_dim_idx = idx
                temp_out = helper.create_variable_for_type_inference('int32')
2487 2488 2489
                fill_constant(
                    [1], 'int32', dim_size, force_cpu=True, out=temp_out
                )
2490 2491 2492 2493 2494 2495 2496
                tensor_list.append(temp_out)
        return tensor_list

    if isinstance(dim, Variable):
        dim.stop_gradient = True
        inputs['AxisTensor'] = dim
    else:
W
wangzhen38 已提交
2497
        assert len(input.shape) + dim >= 0, "(rank(x) + axis) must >= 0"
2498 2499 2500
        dim = (len(input_shape) + dim) if dim < 0 else dim
        attrs['axis'] = dim

G
guosheng 已提交
2501 2502
    if isinstance(num_or_sections, int):
        assert num_or_sections > 1, 'num_or_sections must be more than 1.'
2503
        if isinstance(dim, int) and input_shape[dim] > 0:
2504 2505 2506 2507 2508 2509
            assert input_shape[dim] % num_or_sections == 0, (
                "The input's size along the split dimension "
                "must be evenly divisible by Attr(num_or_sections). "
                "But %d is not evenly divisible by %d. "
                % (num_or_sections, input_shape[dim])
            )
G
guosheng 已提交
2510 2511
        num = num_or_sections
    else:
2512
        if isinstance(dim, int) and input_shape[dim] > 0:
2513 2514 2515
            assert (
                len(num_or_sections) <= input_shape[dim]
            ), 'len(num_or_sections) must not be more than input.shape[dim].'
G
guosheng 已提交
2516
        num = len(num_or_sections)
2517
        attrs['sections'] = list(
2518 2519 2520 2521 2522
            map(
                lambda ele: -1 if isinstance(ele, Variable) else ele,
                num_or_sections,
            )
        )
L
Leo Chen 已提交
2523
        if utils._contain_var(num_or_sections):
2524
            inputs['SectionsTensorList'] = _get_SectionsTensorList(
2525 2526
                num_or_sections
            )
2527

G
guosheng 已提交
2528
    outs = [
X
Xin Pan 已提交
2529
        helper.create_variable_for_type_inference(dtype=helper.input_dtype())
G
guosheng 已提交
2530 2531
        for i in range(num)
    ]
2532 2533 2534
    helper.append_op(
        type='split', inputs=inputs, outputs={'Out': outs}, attrs=attrs
    )
G
guosheng 已提交
2535
    return outs
C
caoying03 已提交
2536 2537 2538


def l2_normalize(x, axis, epsilon=1e-12, name=None):
2539
    r"""
2540

R
ruri 已提交
2541
    This op normalizes `x` along dimension `axis` using an L2
C
caoying03 已提交
2542 2543
    norm. For a 1-D tensor (`dim` is fixed to 0), this layer computes

2544
    .. math::
2545 2546

        y = \\frac{x}{ \sqrt{\sum {x^2} + epsion }}
C
caoying03 已提交
2547 2548 2549 2550 2551

    For `x` with more dimensions, this layer independently normalizes each 1-D
    slice along dimension `axis`.

    Args:
2552
        x(Variable|list): The input tensor could be N-D tensor, and the input data type could be float16, float32 or float64.
2553
        axis(int): The axis on which to apply normalization. If `axis < 0`, \
2554 2555
            the dimension to normalization is rank(X) + axis. -1 is the
            last dimension.
2556
        epsilon(float): The epsilon value is used to avoid division by zero, \
翟飞跃 已提交
2557
            the default value is 1e-12.
2558
    name(str, optional): The default value is None.  Normally there is no need for user to set this property.  For more information, please refer to :ref:`api_guide_Name`
2559

C
caoying03 已提交
2560
    Returns:
R
ruri 已提交
2561
        Variable: The output has the same shape and data type with `x`.
C
caoying03 已提交
2562 2563

    Examples:
2564

2565 2566
    .. code-block:: python
        :name: code-example1
2567

2568
        import paddle
2569

2570 2571
        X = paddle.randn(shape=[3, 5], dtype='float64')
        out = paddle.fluid.layers.l2_normalize(X, axis=-1)
G
Guoxia Wang 已提交
2572
        print(out)
R
ruri 已提交
2573

2574 2575 2576
        # [[ 0.21558504  0.56360189  0.47466096  0.46269539 -0.44326736]
        #  [-0.70602414 -0.52745777  0.37771788 -0.2804768  -0.04449922]
        #  [-0.33972208 -0.43014923  0.31772556  0.76617881 -0.10761525]]
2577

C
caoying03 已提交
2578
    """
F
fengjiayi 已提交
2579 2580
    if len(x.shape) == 1:
        axis = 0
J
Jiabin Yang 已提交
2581
    if _non_static_mode():
2582 2583 2584
        if in_dygraph_mode():
            out, _ = _C_ops.norm(x, 1 if axis is None else axis, epsilon, False)
        elif _in_legacy_dygraph():
2585 2586 2587
            _, out = _legacy_C_ops.norm(
                x, 'axis', 1 if axis is None else axis, 'epsilon', epsilon
            )
2588 2589 2590
        return out

    check_variable_and_dtype(x, "X", ("float16", "float32", "float64"), "norm")
C
caoying03 已提交
2591

2592
    helper = LayerHelper("l2_normalize", **locals())
X
Xin Pan 已提交
2593 2594
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
    norm = helper.create_variable_for_type_inference(dtype=x.dtype)
2595 2596 2597 2598 2599 2600 2601 2602 2603
    helper.append_op(
        type="norm",
        inputs={"X": x},
        outputs={"Out": out, "Norm": norm},
        attrs={
            "axis": 1 if axis is None else axis,
            "epsilon": epsilon,
        },
    )
C
caoying03 已提交
2604
    return out
2605 2606


S
ShenLiang 已提交
2607
@deprecated(since="2.0.0", update_to="paddle.matmul")
S
sneaxiy 已提交
2608
def matmul(x, y, transpose_x=False, transpose_y=False, alpha=1.0, name=None):
G
guosheng 已提交
2609
    """
Y
ying 已提交
2610 2611 2612 2613
    Applies matrix multiplication to two tensors.

    Currently, the input tensors' rank can be any, but when the rank of any
    inputs is bigger than 3, this two inputs' rank should be equal.
G
guosheng 已提交
2614

C
chengduoZH 已提交
2615
    The actual behavior depends on the shapes of :math:`x`, :math:`y` and the
2616
    flag values of :attr:`transpose_x`, :attr:`transpose_y`. Specifically:
G
guosheng 已提交
2617

2618 2619 2620 2621 2622
    - If a transpose flag is specified, the last two dimensions of the tensor
      are transposed. If the tensor is rank-1 of shape :math:`[D]`, then for
      :math:`x` it is treated as :math:`[1, D]` in nontransposed form and as
      :math:`[D, 1]` in transposed form, whereas for :math:`y` it is the
      opposite: It is treated as :math:`[D, 1]` in nontransposed form and as
2623
      :math:`[1, D]` in transposed form.
G
guosheng 已提交
2624

C
chengduoZH 已提交
2625
    - After transpose, the two tensors are 2-D or n-D and matrix multiplication
2626
      performs in the following way.
G
guosheng 已提交
2627

2628
      - If both are 2-D, they are multiplied like conventional matrices.
C
chengduoZH 已提交
2629
      - If either is n-D, it is treated as a stack of matrices residing in the
Y
ying 已提交
2630
        last two dimensions and a batched matrix multiply supporting broadcast
2631
        applies on the two tensors.
G
guosheng 已提交
2632

Y
ying 已提交
2633 2634
    Also note that if the raw tensor :math:`x` or :math:`y` is rank-1 and
    nontransposed, the prepended or appended dimension :math:`1` will be
C
chengduoZH 已提交
2635
    removed after matrix multiplication.
G
guosheng 已提交
2636 2637 2638

    Args:
        x (Variable): The input variable which is a Tensor or LoDTensor.
2639 2640 2641
        y (Variable): The input variable which is a Tensor or LoDTensor.
        transpose_x (bool): Whether to transpose :math:`x` before multiplication.
        transpose_y (bool): Whether to transpose :math:`y` before multiplication.
S
sneaxiy 已提交
2642
        alpha (float): The scale of output. Default 1.0.
2643
        name(str|None): A name for this layer(optional). If set None, the layer
2644
            will be named automatically.
G
guosheng 已提交
2645 2646

    Returns:
石晓伟 已提交
2647
        Variable: The product Tensor (or LoDTensor) variable.
G
guosheng 已提交
2648

G
guosheng 已提交
2649 2650 2651
    Examples:
        .. code-block:: python

2652
            # Examples to clarify shapes of the inputs and output
C
chengduoZH 已提交
2653
            # x: [B, ..., M, K], y: [B, ..., K, N]
2654
            # fluid.layers.matmul(x, y)  # out: [B, ..., M, N]
Y
ying 已提交
2655

2656
            # x: [B, M, K], y: [B, K, N]
2657
            # fluid.layers.matmul(x, y)  # out: [B, M, N]
Y
ying 已提交
2658

2659
            # x: [B, M, K], y: [K, N]
2660
            # fluid.layers.matmul(x, y)  # out: [B, M, N]
Y
ying 已提交
2661

2662
            # x: [M, K], y: [K, N]
2663
            # fluid.layers.matmul(x, y)  # out: [M, N]
Y
ying 已提交
2664 2665

            # x: [B, M, K], y: [K]
2666
            # fluid.layers.matmul(x, y)  # out: [B, M]
Y
ying 已提交
2667

2668
            # x: [K], y: [K]
2669
            # fluid.layers.matmul(x, y)  # out: [1]
2670

Y
ying 已提交
2671
            # x: [M], y: [N]
2672 2673
            # fluid.layers.matmul(x, y, True, True)  # out: [M, N]

2674
            import paddle
2675
            import paddle.fluid as fluid
2676 2677
            paddle.enable_static()

2678 2679 2680
            x = fluid.layers.data(name='x', shape=[2, 3], dtype='float32')
            y = fluid.layers.data(name='y', shape=[3, 2], dtype='float32')
            out = fluid.layers.matmul(x, y, True, True)
G
guosheng 已提交
2681
    """
J
Jiabin Yang 已提交
2682
    if _non_static_mode():
S
ShenLiang 已提交
2683
        out = _varbase_creator(dtype=x.dtype)
2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694
        _legacy_C_ops.matmul(
            x,
            y,
            out,
            'transpose_X',
            transpose_x,
            'transpose_Y',
            transpose_y,
            'alpha',
            float(alpha),
        )
S
ShenLiang 已提交
2695 2696 2697 2698 2699
        return out

    def __check_input(x, y):
        var_names = {'x': x, 'y': y}
        for name, val in var_names.items():
2700 2701 2702
            check_variable_and_dtype(
                val, name, ['float16', 'float32', 'float64'], 'matmul'
            )
S
ShenLiang 已提交
2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715
        x_shape = list(x.shape)
        y_shape = list(y.shape)
        if len(x_shape) == 1:
            x_shape = [1] + x_shape
        if len(y_shape) == 1:
            y_shape = y_shape + [1]

        # check the inner 2 dimensions
        if transpose_x:
            x_shape[-2], x_shape[-1] = x_shape[-1], x_shape[-2]
        if transpose_y:
            y_shape[-2], y_shape[-1] = y_shape[-1], y_shape[-2]
        if x_shape[-1] != y_shape[-2]:
2716 2717 2718 2719 2720 2721
            assert (x_shape[-1] == -1) or (y_shape[-2] == -1), (
                "After performing an optional transpose, Input X's width should be "
                "equal to Y's width for multiplication "
                "prerequisites. But received X's shape: %s, Y's shape: %s\n"
                % (x_shape, y_shape)
            )
S
ShenLiang 已提交
2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732

        if len(y_shape) > 2 and len(x_shape) > 2:
            for i, dim_x in enumerate(x_shape[:-2]):
                # don't check neg shape
                if dim_x < 0 or y_shape[i] < 0:
                    continue
                if dim_x != y_shape[i]:
                    raise ValueError(
                        "When the matrix is larger than 2 dimensions, the higher "
                        "dimensional values of the two matrices need to be equal. "
                        "But received x_shape[%d] != y_shape[%d]. X's shape: %s, "
2733 2734
                        "Y's shape: %s.\n" % (i, i, x_shape, y_shape)
                    )
S
ShenLiang 已提交
2735

W
wanghuancoder 已提交
2736 2737 2738 2739 2740 2741
    attrs = {
        'transpose_X': transpose_x,
        'transpose_Y': transpose_y,
        'alpha': float(alpha),
    }

S
ShenLiang 已提交
2742 2743 2744 2745
    __check_input(x, y)

    helper = LayerHelper('matmul', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
2746 2747 2748 2749 2750 2751
    helper.append_op(
        type='matmul',
        inputs={'X': x, 'Y': y},
        outputs={'Out': out},
        attrs=attrs,
    )
S
ShenLiang 已提交
2752
    return out
2753 2754


2755
def topk(input, k, name=None):
Q
qingqing01 已提交
2756
    """
2757
    :alias_main: paddle.topk
2758 2759
        :alias: paddle.topk,paddle.tensor.topk,paddle.tensor.search.topk
        :old_api: paddle.fluid.layers.topk
2760

2761
    This OP is used to find values and indices of the k largest entries
Q
qingqing01 已提交
2762 2763
    for the last dimension.

2764 2765
    If the input is a 1-D Tensor, finds the k largest entries and outputs
    their values and indices.
Q
qingqing01 已提交
2766 2767 2768 2769

    If the input is a Tensor with higher rank, this operator computes the top k
    entries along the last dimension.

F
fengjiayi 已提交
2770 2771
    .. code-block:: text

2772 2773 2774 2775 2776
        Case 1:

          Input:
            input.shape = [3, 4]
            input.data = [[5, 4, 2, 3],
F
fengjiayi 已提交
2777 2778 2779 2780
                     [9, 7, 10, 25],
                     [6, 2, 10, 1]]
            k = 2

2781
          Output:
F
fengjiayi 已提交
2782
            The first output:
2783 2784
            values.shape = [3, 2]
            values.data = [[5, 4],
F
fengjiayi 已提交
2785 2786 2787 2788
                      [10, 25],
                      [6, 10]]

            The second output:
2789 2790
            indices.shape = [3, 2]
            indices.data = [[0, 1],
F
fengjiayi 已提交
2791 2792 2793
                       [2, 3],
                       [0, 2]]

Q
qingqing01 已提交
2794
    Args:
2795 2796 2797 2798
        input(Variable): The input tensor. Support data types: float32, float64.
        k(int | Variable): The number of top elements to look for along the last dimension
                           of input tensor.
        name (str, optional): Please refer to :ref:`api_guide_Name`, Default None.
Q
qingqing01 已提交
2799 2800

    Returns:
2801 2802
        Values (Variable): Input tensor's k largest elements along each last dimensional slice. The dimension is: :math:`input.shape[:-1]+[k]`.
        Indices (Variable): Indices of k largest elements alone the last dimension of input. The dimension is same as values.
Q
qingqing01 已提交
2803

F
fengjiayi 已提交
2804
    Raises:
2805
        ValueError: If :math:`k < 1` or :math:`k > last dimension of input`.
Q
qingqing01 已提交
2806 2807 2808 2809

    Examples:
        .. code-block:: python

2810
            import paddle.fluid as fluid
2811
            import paddle.fluid.layers as layers
2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824
            # set batch size=None
            input = fluid.data(name="input", shape=[None, 13, 11], dtype='float32')
            top5_values, top5_indices = layers.topk(input, k=5) # top5_values.shape[None, 13, 5], top5_indices.shape=[None, 13, 5]

            # 1D Tensor
            input1 = fluid.data(name="input1", shape=[None, 13], dtype='float32')
            top5_values, top5_indices = layers.topk(input1, k=5) #top5_values.shape=[None, 5], top5_indices.shape=[None, 5]

            # k=Variable
            input2 = fluid.data(name="input2", shape=[None, 13, 11], dtype='float32')
            vk = fluid.data(name="vk", shape=[None, 1], dtype='int32') # save k in vk.data[0]
            vk_values, vk_indices = layers.topk(input2, k=vk) #vk_values.shape=[None, 13, k], vk_indices.shape=[None, 13, k]

Q
qingqing01 已提交
2825
    """
J
Jiabin Yang 已提交
2826
    if _non_static_mode():
2827
        _k = k.numpy().item(0) if isinstance(k, Variable) else k
2828
        out, indices = _legacy_C_ops.top_k(input, 'k', _k)
2829 2830 2831
        out.stop_gradient = True
        indices.stop_gradient = True
        return out, indices
2832

2833 2834
    inputs = {"X": [input]}
    attrs = {}
S
songyouwei 已提交
2835 2836 2837 2838 2839
    if isinstance(k, Variable):
        inputs['K'] = [k]
    else:
        attrs = {'k': k}

2840 2841 2842 2843
    helper = LayerHelper("top_k", **locals())
    values = helper.create_variable_for_type_inference(dtype=input.dtype)
    indices = helper.create_variable_for_type_inference(dtype="int64")

2844 2845 2846 2847 2848 2849
    helper.append_op(
        type="top_k",
        inputs=inputs,
        outputs={"Out": [values], "Indices": [indices]},
        attrs=attrs,
    )
Q
qingqing01 已提交
2850 2851 2852 2853 2854
    values.stop_gradient = True
    indices.stop_gradient = True
    return values, indices


2855 2856 2857
def ctc_greedy_decoder(
    input, blank, input_length=None, padding_value=0, name=None
):
2858
    r"""
S
SunGaofeng 已提交
2859
    This op is used to decode sequences by greedy policy by the following steps:
Y
yi.wu 已提交
2860

S
SunGaofeng 已提交
2861
    1. Get the indexes of maximum value for each row in input. a.k.a.
Y
ying 已提交
2862 2863 2864
       numpy.argmax(input, axis=0).
    2. For each sequence in result of step1, merge repeated tokens between two
       blanks and delete all blanks.
2865

S
SunGaofeng 已提交
2866
    This op is implemented in two modes: lod and padding, either of them can be used.
2867
    The input can be either LoDTensor or Tensor, corresponding to lod and padding
S
SunGaofeng 已提交
2868 2869
    mode respectively.

2870 2871 2872 2873 2874
    A simple example as below:

    .. code-block:: text

        Given:
S
SunGaofeng 已提交
2875
        (1) for lod mode:
2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886

        input.data = [[0.6, 0.1, 0.3, 0.1],
                      [0.3, 0.2, 0.4, 0.1],
                      [0.1, 0.5, 0.1, 0.3],
                      [0.5, 0.1, 0.3, 0.1],

                      [0.5, 0.1, 0.3, 0.1],
                      [0.2, 0.2, 0.2, 0.4],
                      [0.2, 0.2, 0.1, 0.5],
                      [0.5, 0.1, 0.3, 0.1]]

2887
        input.lod = [[4, 4]]
M
minqiyang 已提交
2888

W
whs 已提交
2889
        Computation:
2890

W
whs 已提交
2891 2892 2893 2894 2895 2896
        step1: Apply argmax to first input sequence which is input.data[0:4]. Then we get:
               [[0], [2], [1], [0]]
        step2: merge repeated tokens and remove blank which is 0. Then we get first output sequence:
               [[2], [1]]

        Finally:
2897 2898 2899 2900 2901

        output.data = [[2],
                       [1],
                       [3]]

2902
        output.lod = [[2, 1]]
2903

S
SunGaofeng 已提交
2904
        (2) for padding mode:
2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920

         input.data = [[[0.6, 0.1, 0.3, 0.1],
                        [0.3, 0.2, 0.4, 0.1],
                        [0.1, 0.5, 0.1, 0.3],
                        [0.5, 0.1, 0.3, 0.1]],

                       [[0.5, 0.1, 0.3, 0.1],
                        [0.2, 0.2, 0.2, 0.4],
                        [0.2, 0.2, 0.1, 0.5],
                        [0.5, 0.1, 0.3, 0.1]]]

        input_length.data = [[4], [4]]
        input.shape = [2, 4, 4]

        step1: Apply argmax to first input sequence which is input.data[0:4]. Then we get:
               [[0], [2], [1], [0]], for input.data[4:8] is [[0], [3], [3], [0]], shape is [2,4,1]
2921
        step2: Change the argmax result to use padding mode, then argmax result is
2922 2923 2924 2925 2926 2927 2928 2929 2930
                [[0, 2, 1, 0], [0, 3, 3, 0]], shape is [2, 4], lod is [], input_length is [[4], [4]]
        step3: Apply ctc_align to padding argmax result, padding_value is 0

        Finally:
        output.data = [[2, 1, 0, 0],
                       [3, 0, 0, 0]]
        output_length.data = [[2], [1]]


S
SunGaofeng 已提交
2931
    Parameters:
2932

2933 2934
        input(Variable): the probabilities of variable-length sequences. When in lod mode,
                         it is a 2-D LoDTensor with LoD information. It's shape is [Lp, num_classes + 1]
Y
ying 已提交
2935
                         where Lp is the sum of all input sequences' length and
2936 2937
                         num_classes is the true number of classes. When in padding mode,
                         it is a 3-D Tensor with padding, It's shape is [batch_size, N, num_classes + 1].
S
SunGaofeng 已提交
2938
                         (not including the blank label). The data type can be float32 or float64.
Y
ying 已提交
2939
        blank(int): the blank label index of Connectionist Temporal
S
SunGaofeng 已提交
2940
                    Classification (CTC) loss, which is in the half-opened
Y
ying 已提交
2941
                    interval [0, num_classes + 1).
S
SunGaofeng 已提交
2942 2943
        input_length(Variable, optional): 2-D LoDTensor, shape is [batch_size, 1], data type is int64.
                                 It is used for padding mode. In lod mode, input_length is None.
2944
        padding_value(int): padding value.
2945 2946 2947
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
                             For more information, please refer to :ref:`api_guide_Name`
2948 2949

    Returns:
S
SunGaofeng 已提交
2950 2951 2952 2953 2954
        For lod mode, returns the result of CTC greedy decoder, 2-D LoDTensor, shape is [Lp, 1], \
        data type is int64. 'Lp' is the sum of all output sequences' length. If all the sequences \
        in result were empty, the result LoDTensor will be [-1] with  empty \
        LoD [[]].

2955
        For padding mode, returns a tuple of (output, output_length), which was described as below:
S
SunGaofeng 已提交
2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966

        output, 2-D Tensor, shape is [batch_size, N], data type is int64.

        output_length, 2-D Tensor, shape is [batch_size, 1], data type is int64. It is the length of \
                           each sequence of output for padding mode.

    Return type:
        For lod mode: Variable

        For padding mode: tuple of two Variables (output, output_length).

2967 2968 2969 2970

    Examples:
        .. code-block:: python

2971
            # for lod mode
S
SunGaofeng 已提交
2972
            import paddle.fluid as fluid
S
SunGaofeng 已提交
2973
            x = fluid.data(name='x', shape=[None, 8], dtype='float32', lod_level=1)
2974
            cost = fluid.layers.ctc_greedy_decoder(input=x, blank=0)
2975 2976

            # for padding mode
S
SunGaofeng 已提交
2977 2978
            x_pad = fluid.data(name='x_pad', shape=[10, 4, 8], dtype='float32')
            x_pad_len = fluid.data(name='x_pad_len', shape=[10, 1], dtype='int64')
2979 2980 2981
            out, out_len = fluid.layers.ctc_greedy_decoder(input=x_pad, blank=0,
                            input_length=x_pad_len)

W
wanghaoshuang 已提交
2982
    """
2983 2984 2985
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'ctc_greedy_decoder'
    )
2986

2987
    helper = LayerHelper("ctc_greedy_decoder", **locals())
Q
qingqing01 已提交
2988
    _, topk_indices = topk(input, k=1)
2989 2990

    # ctc align op
X
Xin Pan 已提交
2991
    ctc_out = helper.create_variable_for_type_inference(dtype="int64")
2992 2993

    if input_length is None:
2994 2995 2996 2997 2998 2999
        helper.append_op(
            type="ctc_align",
            inputs={"Input": [topk_indices]},
            outputs={"Output": [ctc_out]},
            attrs={"merge_repeated": True, "blank": blank},
        )
3000 3001 3002
        return ctc_out
    else:
        ctc_out_len = helper.create_variable_for_type_inference(dtype="int64")
3003
        ctc_input = paddle.squeeze(topk_indices, [2])
3004

3005 3006 3007 3008 3009 3010 3011 3012 3013 3014
        helper.append_op(
            type="ctc_align",
            inputs={"Input": [ctc_input], "InputLength": [input_length]},
            outputs={"Output": [ctc_out], "OutputLength": [ctc_out_len]},
            attrs={
                "merge_repeated": True,
                "blank": blank,
                "padding_value": padding_value,
            },
        )
3015
        return ctc_out, ctc_out_len
3016 3017


3018 3019 3020 3021 3022 3023 3024 3025 3026
def im2sequence(
    input,
    filter_size=1,
    stride=1,
    padding=0,
    input_image_size=None,
    out_stride=1,
    name=None,
):
3027
    r"""
3028 3029
    :api_attr: Static Graph

3030
    Extracts image patches from the input tensor to form a tensor of shape
L
Liufang Sang 已提交
3031 3032 3033
    {input.batch_size * output_height * output_width, filter_size_height *
    filter_size_width * input.channels}. This op use filter to scan images
    and convert these images to sequences. After expanding, the number of time step are
3034 3035
    output_height * output_width for an image, in which output_height and
    output_width are calculated by below equation:
3036 3037 3038

    .. math::

L
Liufang Sang 已提交
3039 3040 3041 3042
        output\_height  = 1 + \
            (padding\_up + padding\_down + input\_height  - filter\_size\_height  + stride\_height - 1) / stride\_height \\\\
        output\_width  = 1 + \
            (padding\_left + padding\_right + input\_width  - filter\_size\_width  + stride\_width - 1) / stride\_width
3043

L
Liufang Sang 已提交
3044
    And the dimension of each time step is filter_size_height * filter_size_width * input.channels.
3045

L
Liufang Sang 已提交
3046 3047
    Parameters:
        input (Variable): The input should be a 4-D Tensor in :math:`NCHW` format. The data type is float32.
W
wanghaoshuang 已提交
3048

L
Liufang Sang 已提交
3049 3050 3051
        filter_size(int32 | List[int32]): The filter size. If filter_size is a List,
            it must contain two integers, :math:`[filter\_size\_height, filter\_size\_width]` .
            Otherwise, the filter size will be a square :math:`[filter\_size, filter\_size]` . Default is 1.
3052

L
Liufang Sang 已提交
3053 3054
        stride(int32 | List[int32]): The stride size. If stride is a List, it must
            contain two integers, :math:`[stride\_height, stride\_width]` . Otherwise, the stride size will be a square :math:`[stride\_size, stride\_size]` . Default is 1.
3055

L
Liufang Sang 已提交
3056 3057 3058 3059 3060
        padding(int32 | List[int32]): The padding size. If padding is a List, it can
            contain four integers like :math:`[padding\_up, padding\_left, padding\_down, padding\_right]` to indicate
            paddings of four direction.  Or it can contain two integers :math:`[padding\_height, padding\_width]` which means
            padding_up = padding_down = padding_height and
            padding_left = padding_right = padding_width. Otherwise, a scalar padding means
3061
            padding_up = padding_down = padding_left = padding_right = padding.
L
Liufang Sang 已提交
3062
            Default is 0.
3063

L
Liufang Sang 已提交
3064 3065 3066 3067
        input_image_size(Variable, optional): the input contains image real size.It's dim
            is :math:`[batchsize, 2]` . It is just for batch inference when not None. Default is None.

        out_stride(int32 | List[int32]): The scaling of image through CNN. It is valid only when input_image_size is not None.
T
tianshuo78520a 已提交
3068
            If out_stride is List,  it must contain two integers,
L
Liufang Sang 已提交
3069 3070 3071 3072 3073
            :math:`[out\_stride\_height, out\_stride\_W]` . Otherwise,
            the out_stride_height = out_stride_width = out_stride. Default is 1.

        name (str, optional): The default value is None.  Normally there is no need for
                    user to set this property.  For more information, please refer to :ref:`api_guide_Name` .
3074 3075 3076

    Returns:
            The output is a 2-D LoDTensor with shape {input.batch\_size * output\_height * output\_width, \
L
Liufang Sang 已提交
3077 3078 3079
            filter\_size\_height * filter\_size\_width * input.channels}. The data type is float32.

    Return Type: Variable
3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106

    Examples:

        .. code-block:: text

            Given:

            x = [[[[ 6.  2.  1.]
                   [ 8.  3.  5.]
                   [ 0.  2.  6.]]

                  [[ 2.  4.  4.]
                   [ 6.  3.  0.]
                   [ 6.  4.  7.]]]

                 [[[ 6.  7.  1.]
                   [ 5.  7.  9.]
                   [ 2.  4.  8.]]

                  [[ 1.  2.  1.]
                   [ 1.  3.  5.]
                   [ 9.  0.  8.]]]]

            x.dims = {2, 2, 3, 3}

            And:

W
wanghaoshuang 已提交
3107 3108 3109
            filter = [2, 2]
            stride = [1, 1]
            padding = [0, 0]
3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121

            Then:

            output.data = [[ 6.  2.  8.  3.  2.  4.  6.  3.]
                           [ 2.  1.  3.  5.  4.  4.  3.  0.]
                           [ 8.  3.  0.  2.  6.  3.  6.  4.]
                           [ 3.  5.  2.  6.  3.  0.  4.  7.]
                           [ 6.  7.  5.  7.  1.  2.  1.  3.]
                           [ 7.  1.  7.  9.  2.  1.  3.  5.]
                           [ 5.  7.  2.  4.  1.  3.  9.  0.]
                           [ 7.  9.  4.  8.  3.  5.  0.  8.]]

3122
            output.dims = {8, 8}
3123

3124
            output.lod = [[4, 4]]
3125

T
Tink_Y 已提交
3126
    Examples:
3127 3128 3129

        .. code-block:: python

B
Bai Yifan 已提交
3130
            import paddle.fluid as fluid
3131 3132
            import paddle
            paddle.enable_static()
L
Liufang Sang 已提交
3133
            data = fluid.data(name='data', shape=[None, 3, 32, 32],
B
Bai Yifan 已提交
3134
                                     dtype='float32')
3135
            output = fluid.layers.im2sequence(
B
Bai Yifan 已提交
3136 3137
                input=data, stride=[1, 1], filter_size=[2, 2])

3138 3139

    """
3140 3141 3142
    assert (
        not _non_static_mode()
    ), "sequence layer is not supported in dygraph mode yet."
W
wanghaoshuang 已提交
3143

3144 3145
    check_variable_and_dtype(input, 'input', ['float32'], 'im2sequence')

W
wanghaoshuang 已提交
3146 3147 3148 3149 3150 3151 3152 3153 3154
    if isinstance(filter_size, int):
        filter_size = [filter_size, filter_size]
    if isinstance(stride, int):
        stride = [stride, stride]
    if isinstance(padding, int):
        padding = [padding, padding]
    if len(padding) == 2:
        padding.append(padding[0])
        padding.append(padding[1])
3155
    inputs = {"X": input}
3156
    attrs = {"kernels": filter_size, "strides": stride, "paddings": padding}
3157 3158 3159 3160 3161
    if input_image_size:
        if isinstance(out_stride, int):
            out_stride = [out_stride, out_stride]
        inputs["Y"] = input_image_size
        attrs["out_stride"] = out_stride
3162
    helper = LayerHelper('im2sequence', **locals())
X
Xin Pan 已提交
3163
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
3164 3165 3166
    helper.append_op(
        type='im2sequence', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
3167
    return out
3168 3169


Y
yuyang18 已提交
3170
@templatedoc()
3171
def row_conv(input, future_context_size, param_attr=None, act=None):
Y
yuyang18 已提交
3172
    """
3173 3174
    :api_attr: Static Graph

Y
yuyang18 已提交
3175
    ${comment}
3176 3177

    Args:
Y
yuyang18 已提交
3178
        input (${x_type}): ${x_comment}.
Y
yangyaming 已提交
3179 3180
        future_context_size (int): Future context size. Please note, the shape
            of convolution kernel is [future_context_size + 1, D].
3181 3182 3183 3184 3185
        param_attr (ParamAttr): Attributes of parameters, including
            name, initializer etc.
        act (str): Non-linear activation to be applied to output variable.

    Returns:
Y
yuyang18 已提交
3186
        ${out_comment}.
3187 3188

    Examples:
B
Bai Yifan 已提交
3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200

      .. code-block:: python

        # for LodTensor inputs
        import paddle
        paddle.enable_static()
        x = paddle.static.data(name='x', shape=[9, 16],
                               dtype='float32', lod_level=1)
        out = paddle.static.nn.row_conv(input=x, future_context_size=2)
        # for Tensor inputs
        x = paddle.static.data(name='x', shape=[9, 4, 16], dtype='float32')
        out = paddle.static.nn.row_conv(input=x, future_context_size=2)
3201 3202
    """
    helper = LayerHelper('row_conv', **locals())
3203
    check_variable_and_dtype(input, 'input', ['float32'], 'row_conv')
3204
    dtype = helper.input_dtype()
3205
    filter_shape = [future_context_size + 1, input.shape[-1]]
3206 3207 3208
    filter_param = helper.create_parameter(
        attr=helper.param_attr, shape=filter_shape, dtype=dtype
    )
X
Xin Pan 已提交
3209
    out = helper.create_variable_for_type_inference(dtype)
3210 3211 3212 3213 3214
    helper.append_op(
        type='row_conv',
        inputs={'X': [input], 'Filter': [filter_param]},
        outputs={'Out': [out]},
    )
Y
yangyaming 已提交
3215
    return helper.append_activation(out)
3216 3217


Y
yuyang18 已提交
3218
@templatedoc()
3219
def multiplex(inputs, index, name=None):
3220
    """
Y
yuyang18 已提交
3221

3222
    Based on the given index parameter, the OP selects a specific row from each input Tensor to construct the output Tensor.
L
lujun 已提交
3223

3224
    If the input of this OP contains :math:`m` Tensors, where :math:`I_{i}` means the i-th input Tensor, :math:`i` between :math:`[0,m)` .
L
lujun 已提交
3225

3226
    And :math:`O` means the output, where :math:`O[i]` means the i-th row of the output, then the output satisfies that :math:`O[i] = I_{index[i]}[i]` .
L
lujun 已提交
3227

3228
    For Example:
L
lujun 已提交
3229

3230
            .. code-block:: text
L
lujun 已提交
3231

3232
                Given:
L
lujun 已提交
3233

3234 3235 3236 3237
                inputs = [[[0,0,3,4], [0,1,3,4], [0,2,4,4], [0,3,3,4]],
                          [[1,0,3,4], [1,1,7,8], [1,2,4,2], [1,3,3,4]],
                          [[2,0,3,4], [2,1,7,8], [2,2,4,2], [2,3,3,4]],
                          [[3,0,3,4], [3,1,7,8], [3,2,4,2], [3,3,3,4]]]
L
lujun 已提交
3238

3239
                index = [[3],[0],[1],[2]]
L
lujun 已提交
3240

3241 3242 3243 3244
                out = [[3,0,3,4],    # out[0] = inputs[index[0]][0] = inputs[3][0] = [3,0,3,4]
                       [0,1,3,4],    # out[1] = inputs[index[1]][1] = inputs[0][1] = [0,1,3,4]
                       [1,2,4,2],    # out[2] = inputs[index[2]][2] = inputs[1][2] = [1,2,4,2]
                       [2,3,3,4]]    # out[3] = inputs[index[3]][3] = inputs[2][3] = [2,3,3,4]
L
lujun 已提交
3245 3246


3247
    Args:
3248 3249 3250 3251 3252
        inputs (list): The input Tensor list. The list elements are N-D Tensors of data types float32, float64, int32, int64. All input Tensor shapes should be the same and rank must be at least 2.
        index (Tensor): Used to select some rows in the input Tensor to construct an index of the output Tensor. It is a 2-D Tensor with data type int32 or int64 and shape [M, 1], where M is the number of input Tensors.
        name(str, optional): The default value is None. Normally there is no
            need for user to set this property. For more information, please
            refer to :ref:`api_guide_Name`.
3253
    Returns:
3254
        Tensor: Output of multiplex OP, with data type being float32, float64, int32, int64.
X
xuezhong 已提交
3255 3256

    Examples:
3257

X
xuezhong 已提交
3258 3259
        .. code-block:: python

3260
            import paddle
3261 3262 3263
            import numpy as np
            img1 = np.array([[1, 2], [3, 4]]).astype(np.float32)
            img2 = np.array([[5, 6], [7, 8]]).astype(np.float32)
3264 3265 3266
            inputs = [paddle.to_tensor(img1), paddle.to_tensor(img2)]
            index = paddle.to_tensor(np.array([[1], [0]]).astype(np.int32))
            res = paddle.multiplex(inputs, index)
3267
            print(res) # [array([[5., 6.], [3., 4.]], dtype=float32)]
X
xuezhong 已提交
3268

3269
    """
3270 3271

    if _in_legacy_dygraph():
3272
        return _legacy_C_ops.multiplex(index, inputs)
3273
    if in_dygraph_mode():
3274
        return _C_ops.multiplex(inputs, index)
3275 3276
    helper = LayerHelper('multiplex', **locals())

3277 3278 3279
    check_type(inputs, 'inputs', (list), 'multiplex')
    if len(inputs) < 2:
        raise ValueError(
3280 3281
            "inputs should be a list object with at least 2 elements."
        )
3282
    for id, x in enumerate(inputs):
3283 3284 3285 3286 3287 3288
        check_variable_and_dtype(
            x,
            'input[' + str(id) + ']',
            ['float32', 'float64', 'int32', 'int64'],
            'multiplex',
        )
3289
    check_variable_and_dtype(index, "index", ['int32', 'int64'], 'multiplex')
3290 3291

    out = helper.create_variable_for_type_inference(inputs[0].dtype)
3292 3293 3294 3295 3296
    helper.append_op(
        type='multiplex',
        inputs={'X': inputs, 'Ids': index},
        outputs={'Out': [out]},
    )
3297
    return out
X
xuezhong 已提交
3298 3299


3300 3301
def smooth_l1(x, y, inside_weight=None, outside_weight=None, sigma=None):
    """
3302

Y
Yibing Liu 已提交
3303 3304
    This layer computes the smooth L1 loss for Variable :attr:`x` and :attr:`y`.
    It takes the first dimension of :attr:`x` and :attr:`y` as batch size.
Q
qingqing01 已提交
3305
    For each instance, it computes the smooth L1 loss element by element first
T
tianshuo78520a 已提交
3306
    and then sums all the losses. So the shape of output Variable is
3307
    [batch_size, 1].
3308

3309 3310
    Args:
        x (Variable): A tensor with rank at least 2. The input value of smooth
Q
qingqing01 已提交
3311
            L1 loss op with shape [batch_size, dim1, ..., dimN].
3312
            A LoDTensor or Tensor with type float32.
3313
        y (Variable): A tensor with rank at least 2. The target value of smooth
Y
Yibing Liu 已提交
3314
            L1 loss op with same shape as :attr:`x`.
3315
            A LoDTensor or Tensor with type float32.
3316
        inside_weight (Variable|None):  A tensor with rank at least 2. This
3317 3318
            input is optional and should have same shape with :attr:`x`. If
            provided, the result of (:attr:`x` - :attr:`y`) will be multiplied
Y
Yibing Liu 已提交
3319
            by this tensor element by element.
3320
            A Tensor with type float32.
3321
        outside_weight (Variable|None): A tensor with rank at least 2. This
3322 3323
            input is optional and should have same shape with :attr:`x`. If
            provided, the out smooth L1 loss will be multiplied by this tensor
Y
Yibing Liu 已提交
3324
            element by element.
3325
            A Tensor with type float32.
3326
        sigma (float|None): Hyper parameter of smooth L1 loss layer. A float
3327 3328
           scalar with default value 1.0.

3329
    Returns:
3330
        Variable: The output smooth L1 loss with shape [batch_size, 1].  A Tensor with type float32.
3331 3332 3333 3334

    Examples:
        .. code-block:: python

3335
            import paddle.fluid as fluid
3336
            import numpy as np
3337 3338
            import paddle
            paddle.enable_static()
3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349
            data = fluid.data(name="x", shape=[-1, 3], dtype="float32")
            label = fluid.data(name="y", shape=[-1, 3], dtype="float32")
            result = fluid.layers.smooth_l1(data,label)
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
            x = np.random.rand(3,3).astype("float32")
            y = np.random.rand(3,3).astype("float32")
            output= exe.run(feed={"x":x, "y":y},
                             fetch_list=[result])
            print(output)
3350

3351 3352 3353 3354
            #[array([[0.08220536],
            #       [0.36652038],
            #      [0.20541131]], dtype=float32)]

3355
    """
3356 3357
    check_variable_and_dtype(x, 'X', ['float32', 'float64'], 'smooth_l1_loss')
    check_variable_and_dtype(y, 'Y', ['float32', 'float64'], 'smooth_l1_loss')
3358

3359
    helper = LayerHelper('smooth_l1_loss', **locals())
3360

X
Xin Pan 已提交
3361 3362
    diff = helper.create_variable_for_type_inference(dtype=x.dtype)
    loss = helper.create_variable_for_type_inference(dtype=x.dtype)
3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373
    helper.append_op(
        type='smooth_l1_loss',
        inputs={
            'X': x,
            'Y': y,
            'InsideWeight': inside_weight,
            'OutsideWeight': outside_weight,
        },
        outputs={'Diff': diff, 'Out': loss},
        attrs={'sigma': sigma if sigma is not None else 1.0},
    )
3374
    return loss
3375 3376


3377
@deprecated(since='2.0.0', update_to='paddle.nn.functional.one_hot')
3378
def one_hot(input, depth, allow_out_of_range=False):
3379
    """
3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417

    **WARING:** This OP requires the last dimension of Tensor shape must be equal to 1.
    This OP will be deprecated in a future release. It is recommended to use fluid. :ref:`api_fluid_one_hot` .

    The operator converts each id in the input to an one-hot vector with a
    :attr:`depth` length. The value in the vector dimension corresponding to the id
    is 1, and the value in the remaining dimension is 0.

    The shape of output Tensor or LoDTensor is generated by adding :attr:`depth` dimension
    behind the last dimension of the input shape.

    .. code-block:: text

        Example 1 (allow_out_of_range=False):

        input:
            X.shape = [4, 1]
            X.data = [[1], [1], [3], [0]]
            depth = 4

        output:
            Out.shape = [4, 4]
            Out.data = [[0., 1., 0., 0.],
                        [0., 1., 0., 0.],
                        [0., 0., 0., 1.],
                        [1., 0., 0., 0.]]

        Example 2 (allow_out_of_range=True):

        input:
            X.shape = [4, 1]
            X.data = [[1], [1], [5], [0]]
            depth = 4
            allow_out_of_range = True

        output:
            Out.shape = [4, 4]
            Out.data = [[0., 1., 0., 0.],
3418
                        [0., 1., 0., 0.],
3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430
                        [0., 0., 0., 0.], # This id is 5, which goes beyond depth, so set it all-zeros data.
                        [1., 0., 0., 0.]]

        Example 3 (allow_out_of_range=False):

        input:
            X.shape = [4, 1]
            X.data = [[1], [1], [5], [0]]
            depth = 4
            allow_out_of_range = False

        output: Throw an exception for Illegal value
3431
            The second dimension in X is 5, which is greater than depth.
3432 3433
            Allow_out_of_range =False means that does not allow the word id to exceed depth,
            so it throws an exception.
3434 3435

    Args:
3436 3437 3438
        input(Variable): Tensor or LoDTensor with shape :math:`[N_1, N_2, ..., N_k, 1]` ,
            which contains at least one dimension and the last dimension must be 1.
            The data type is int32 or int64.
3439
        depth(scalar): An integer defining the :attr:`depth` of the one hot dimension. If input
3440
            is word id, depth is generally the dictionary size.
3441
        allow_out_of_range(bool): A bool value indicating whether the input
3442 3443 3444 3445
            indices could be out of range :math:`[0, depth)` . When input indices are
            out of range, exceptions :code:`Illegal value` is raised if :attr:`allow_out_of_range`
            is False, or zero-filling representations is created if it is set True.
            Default: False.
3446 3447

    Returns:
3448
        Variable: The one-hot representations of input. A Tensor or LoDTensor with type float32.
3449 3450

    Examples:
C
caoying03 已提交
3451
        .. code-block:: python
3452

3453
            import paddle
3454
            import paddle.fluid as fluid
3455 3456
            paddle.enable_static()

3457 3458 3459
            # Correspond to the first example above, where label.shape is [4, 1] and one_hot_label.shape is [4, 4].
            label = fluid.data(name="label", shape=[4, 1], dtype="int64")
            one_hot_label = fluid.layers.one_hot(input=label, depth=4)
3460
    """
J
Jiabin Yang 已提交
3461
    if _non_static_mode():
S
songyouwei 已提交
3462 3463 3464
        if isinstance(depth, Variable):
            depth = depth.numpy()
            assert depth.shape == (
3465 3466
                1,
            ), "depth of type Variable should have shape [1]"
3467
            depth = depth.item(0)
3468 3469 3470
        out = _legacy_C_ops.one_hot(
            input, 'depth', depth, 'allow_out_of_range', allow_out_of_range
        )
3471 3472
        out.stop_gradient = True
        return out
3473

3474
    helper = LayerHelper("one_hot", **locals())
3475
    check_variable_and_dtype(input, 'input', ['int32', 'int64'], 'one_hot')
3476
    check_type(depth, 'depth', (int, Variable), 'one_hot')
X
Xin Pan 已提交
3477
    one_hot_out = helper.create_variable_for_type_inference(dtype='float32')
3478

3479 3480
    if not isinstance(depth, Variable):
        # user attribute
3481
        inputs = {'X': input}
Y
Yi Liu 已提交
3482
        attrs = {'depth': depth, 'allow_out_of_range': allow_out_of_range}
3483
    else:
3484 3485 3486
        depth.stop_gradient = True
        inputs = {'X': input, 'depth_tensor': depth}
        attrs = {'allow_out_of_range': allow_out_of_range}
3487 3488 3489
    helper.append_op(
        type="one_hot", inputs=inputs, attrs=attrs, outputs={'Out': one_hot_out}
    )
3490
    one_hot_out.stop_gradient = True
3491
    return one_hot_out
Y
Yu Yang 已提交
3492 3493


Y
Yu Yang 已提交
3494
def autoincreased_step_counter(counter_name=None, begin=1, step=1):
Y
Yu Yang 已提交
3495
    """
3496 3497
    :api_attr: Static Graph

3498 3499
    Create an auto-increase variable. which will be automatically increased
    by 1 in every iteration. By default, the first return of this counter is 1,
Y
Yibing Liu 已提交
3500
    and the step size is 1.
Y
Yu Yang 已提交
3501 3502

    Args:
Y
Yibing Liu 已提交
3503 3504 3505
        counter_name(str, optional): The counter name. Default '@STEP_COUNTER@'.
        begin(int, optional): The first return value of this counter. Default 1.
        step(int, optional): The step size. Default 1.
Y
Yu Yang 已提交
3506

3507
    Returns:
Y
Yibing Liu 已提交
3508
        Variable: The auto-increased Variable with data type int64.
Y
yi.wu 已提交
3509 3510 3511 3512

    Examples:
        .. code-block:: python

3513
           import paddle.fluid as fluid
3514 3515
           import paddle
           paddle.enable_static()
Y
yi.wu 已提交
3516
           global_step = fluid.layers.autoincreased_step_counter(
Y
Yibing Liu 已提交
3517
               counter_name='@LR_DECAY_COUNTER@', begin=0, step=1)
Y
Yu Yang 已提交
3518 3519
    """
    helper = LayerHelper('global_step_counter')
Y
Yu Yang 已提交
3520 3521
    if counter_name is None:
        counter_name = '@STEP_COUNTER@'
Y
Yu Yang 已提交
3522
    counter, is_new_var = helper.create_or_get_global_variable(
H
hong 已提交
3523 3524 3525 3526
        name=counter_name,
        dtype='int64',
        shape=[1],
        persistable=True,
3527 3528
        belong_to_optimizer=True,
    )
Y
Yu Yang 已提交
3529
    if is_new_var:
3530 3531 3532
        helper.set_variable_initializer(
            counter, initializer=Constant(value=begin - 1, force_cpu=True)
        )
W
Wu Yi 已提交
3533
        helper.main_program.global_block()._prepend_op(
Y
Yu Yang 已提交
3534 3535
            type='increment',
            inputs={'X': [counter]},
Y
Yu Yang 已提交
3536
            outputs={'Out': [counter]},
3537 3538
            attrs={'step': float(step)},
        )
Y
Yu Yang 已提交
3539 3540 3541
        counter.stop_gradient = True

    return counter
Y
yangyaming 已提交
3542 3543


3544
def unsqueeze(input, axes, name=None):
Y
Yibing Liu 已提交
3545
    """
3546
    Insert single-dimensional entries to the shape of a Tensor. Takes one
M
minqiyang 已提交
3547 3548
    required argument axes, a list of dimensions that will be inserted.
    Dimension indices in axes are as seen in the output tensor.
Y
Yibing Liu 已提交
3549

M
minqiyang 已提交
3550
    For example:
H
haowang101779990 已提交
3551 3552 3553

    .. code-block:: text

M
minqiyang 已提交
3554
      Given a tensor such that tensor with shape [3, 4, 5],
Y
Yibing Liu 已提交
3555
      then Unsqueezed tensor with axes=[0, 4] has shape [1, 3, 4, 5, 1].
M
minqiyang 已提交
3556

Y
Yibing Liu 已提交
3557
    Args:
3558
        input (Variable): The input Tensor to be unsqueezed. Supported data type: float32, float64, bool, int8, int32, int64.
3559
        axes (int|list|tuple|Variable): Indicates the dimensions to be inserted. The data type is ``int32`` . If ``axes`` is a list or tuple, the elements of it should be integers or Tensors with shape [1]. If ``axes`` is an Variable, it should be an 1-D Tensor .
3560
        name (str|None): Name for this layer.
Y
Yibing Liu 已提交
3561 3562

    Returns:
3563
        Variable: Unsqueezed Tensor, with the same data type as input.
Y
Yibing Liu 已提交
3564 3565 3566 3567

    Examples:
        .. code-block:: python

3568 3569 3570
            import paddle.fluid as fluid
            x = fluid.layers.data(name='x', shape=[5, 10])
            y = fluid.layers.unsqueeze(input=x, axes=[1])
3571

Y
Yibing Liu 已提交
3572
    """
J
Jiabin Yang 已提交
3573
    if _non_static_mode():
L
Leo Chen 已提交
3574 3575 3576
        if isinstance(axes, int):
            axes = [axes]
        elif isinstance(axes, Variable):
3577
            axes = axes.numpy().tolist()
L
Leo Chen 已提交
3578 3579 3580 3581 3582
        elif isinstance(axes, (list, tuple)):
            axes = [
                item.numpy().item(0) if isinstance(item, Variable) else item
                for item in axes
            ]
3583
        if _in_legacy_dygraph():
3584
            out, _ = _legacy_C_ops.unsqueeze2(input, 'axes', axes)
3585
            return out
3586
        return _C_ops.unsqueeze(input, axes)
3587 3588

    check_type(axes, 'axis/axes', (int, list, tuple, Variable), 'unsqueeze')
3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605
    check_variable_and_dtype(
        input,
        'input',
        [
            'float16',
            'float32',
            'float64',
            'bool',
            'int8',
            'int16',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        'unsqueeze',
    )
3606 3607 3608 3609 3610 3611 3612 3613 3614 3615
    helper = LayerHelper("unsqueeze2", **locals())
    inputs = {"X": input}
    attrs = {}

    if isinstance(axes, int):
        axes = [axes]
    if isinstance(axes, Variable):
        axes.stop_gradient = True
        inputs["AxesTensor"] = axes
    elif isinstance(axes, (list, tuple)):
L
Leo Chen 已提交
3616
        if utils._contain_var(axes):
3617
            inputs["AxesTensorList"] = utils._convert_to_tensor_list(axes)
3618 3619 3620
        else:
            attrs["axes"] = axes

X
Xin Pan 已提交
3621 3622
    out = helper.create_variable_for_type_inference(dtype=input.dtype)
    x_shape = helper.create_variable_for_type_inference(dtype=input.dtype)
3623 3624 3625 3626 3627 3628
    helper.append_op(
        type="unsqueeze2",
        inputs=inputs,
        attrs=attrs,
        outputs={"Out": out, "XShape": x_shape},
    )
Y
Yibing Liu 已提交
3629

3630 3631
    return out

3632

Y
yangyaming 已提交
3633
def lod_reset(x, y=None, target_lod=None):
Y
yangyaming 已提交
3634
    """
Y
Yibing Liu 已提交
3635
    Set LoD of :attr:`x` to a new one specified by :attr:`y` or
3636 3637 3638 3639
    :attr:`target_lod`. When :attr:`y` provided, :attr:`y.lod` would be
    considered as target LoD first, otherwise :attr:`y.data` would be
    considered as target LoD. If :attr:`y` is not provided, target LoD should
    be specified by :attr:`target_lod`. If target LoD is specified by
3640
    :attr:`y.data` or :attr:`target_lod`, only one level LoD is supported.
Y
yangyaming 已提交
3641 3642 3643 3644 3645 3646

    .. code-block:: text

        * Example 1:

            Given a 1-level LoDTensor x:
3647
                x.lod =  [[ 2,           3,                   1 ]]
Y
yangyaming 已提交
3648 3649 3650
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

3651
            target_lod: [4, 2]
Y
yangyaming 已提交
3652 3653

            then we get a 1-level LoDTensor:
3654
                out.lod =  [[4,                          2]]
Y
yangyaming 已提交
3655 3656 3657 3658 3659 3660
                out.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                out.dims = [6, 1]

        * Example 2:

            Given a 1-level LoDTensor x:
3661
                x.lod =  [[2,            3,                   1]]
Y
yangyaming 已提交
3662 3663 3664 3665
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

            y is a Tensor:
3666
                y.data = [[2, 4]]
Y
yangyaming 已提交
3667 3668 3669
                y.dims = [1, 3]

            then we get a 1-level LoDTensor:
3670
                out.lod =  [[2,            4]]
Y
yangyaming 已提交
3671 3672 3673 3674 3675 3676
                out.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                out.dims = [6, 1]

        * Example 3:

            Given a 1-level LoDTensor x:
3677
                x.lod =  [[2,            3,                   1]]
Y
yangyaming 已提交
3678 3679 3680 3681
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

            y is a 2-level LoDTensor:
3682
                y.lod =  [[2, 2], [2, 2, 1, 1]]
Y
yangyaming 已提交
3683 3684 3685 3686
                y.data = [[1.1], [2.1], [3.1], [4.1], [5.1], [6.1]]
                y.dims = [6, 1]

            then we get a 2-level LoDTensor:
3687
                out.lod =  [[2, 2], [2, 2, 1, 1]]
Y
yangyaming 已提交
3688 3689 3690 3691
                out.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                out.dims = [6, 1]

    Args:
3692
        x (Variable): Input variable which could be a Tensor or LoDTensor.
3693
                      The data type should be int32, int64, float32 or float64.
3694 3695
        y (Variable, optional): If provided, output's LoD would be derived from :attr:`y`.
                                If y's lod level>0, the data type can be any type.
3696 3697
                                If y's lod level=0, the data type should be int32.
        target_lod (list|tuple, optional): One level LoD which should be considered
Y
Yibing Liu 已提交
3698
                                      as target LoD when :attr:`y` not provided.
Y
yangyaming 已提交
3699 3700

    Returns:
Y
Yibing Liu 已提交
3701
        Variable: Output variable with LoD specified by this layer.
Y
yangyaming 已提交
3702 3703

    Raises:
Y
Yibing Liu 已提交
3704
        ValueError: If :attr:`y` and :attr:`target_lod` are both None.
Y
yangyaming 已提交
3705 3706 3707 3708

    Examples:
        .. code-block:: python

3709
            import paddle.fluid as fluid
3710 3711 3712
            x = fluid.layers.data(name='x', shape=[10])
            y = fluid.layers.data(name='y', shape=[10, 20], lod_level=2)
            out = fluid.layers.lod_reset(x=x, y=y)
Y
yangyaming 已提交
3713
    """
3714 3715 3716
    check_variable_and_dtype(
        x, 'x', ['float32', 'float64', 'int32', 'int64'], 'lod_reset'
    )
Y
yangyaming 已提交
3717
    helper = LayerHelper("lod_reset", **locals())
X
Xin Pan 已提交
3718
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
Y
yangyaming 已提交
3719
    if y is not None:
3720
        check_type(y, 'y', (Variable), 'lod_reset')
3721 3722 3723 3724
        # TODO: check y.lod_level = 0 dtype
        helper.append_op(
            type="lod_reset", inputs={'X': x, 'Y': y}, outputs={'Out': out}
        )
Y
yangyaming 已提交
3725
    elif target_lod is not None:
3726 3727 3728 3729 3730 3731
        helper.append_op(
            type="lod_reset",
            inputs={'X': x},
            attrs={'target_lod': target_lod},
            outputs={'Out': out},
        )
Y
yangyaming 已提交
3732
    else:
3733 3734 3735 3736
        raise ValueError("y and target_lod should not be both none.")
    return out


3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747
def image_resize(
    input,
    out_shape=None,
    scale=None,
    name=None,
    resample='BILINEAR',
    actual_shape=None,
    align_corners=True,
    align_mode=1,
    data_format='NCHW',
):
3748
    """
3749

R
ruri 已提交
3750
    This op resizes a batch of images.
F
stash  
fengjiayi 已提交
3751

3752 3753
    The input must be a 3-D Tensor of the shape (num_batches, channels, in_w)
    or a 4-D Tensor of the shape (num_batches, channels, in_h, in_w)
3754 3755
    or (num_batches, in_h, in_w, channels), or a 5-D Tensor of the shape
    (num_batches, channels, in_d, in_h, in_w) or (num_batches, in_d, in_h, in_w, channels),
T
tianshuo78520a 已提交
3756
    and the resizing only applies on the three dimensions(depth, height and width).
3757

3758
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in the
3759 3760
    future and only use :attr:`out_shape` instead.

3761
    Supporting resample methods:
3762
        'LINEAR' : Linear interpolation
Q
update  
qiaolongfei 已提交
3763

3764
        'BILINEAR' : Bilinear interpolation
T
Tink_Y 已提交
3765

K
Kaipeng Deng 已提交
3766 3767
        'TRILINEAR' : Trilinear interpolation

3768
        'NEAREST' : Nearest neighbor interpolation
3769

3770
        'BICUBIC' : Bicubic interpolation
3771 3772

    Linear interpolation is the method of using a line connecting two known quantities
3773
    to determine the value of an unknown quantity between the two known quantities.
3774

3775
    Nearest neighbor interpolation is to perform nearest neighbor interpolation
3776
    in both the 3rd dimension(in height direction) and the 4th dimension(in width
3777
    direction) on input tensor.
3778 3779 3780 3781 3782

    Bilinear interpolation is an extension of linear interpolation for
    interpolating functions of two variables (e.g. H-direction and
    W-direction in this op) on a rectilinear 2D grid. The key idea is
    to perform linear interpolation first in one direction, and then
3783 3784
    again in the other direction.

3785 3786 3787
    Trilinear interpolation is an extension of linear interpolation for
    interpolating functions of three variables (e.g. D-direction,
    H-direction and W-direction in this op) on a rectilinear 3D grid.
K
Kaipeng Deng 已提交
3788
    The linear interpolation is performed on three directions.
3789

3790 3791 3792 3793
    Bicubic interpolation is an extension of cubic interpolation for interpolating
    data points on a two-dimensional regular grid. The interpolated surface is
    smoother than corresponding surfaces obtained by bilinear interpolation or
    nearest-neighbor interpolation.
K
Kaipeng Deng 已提交
3794

3795
    Align_corners and align_mode are optional parameters,the calculation method
3796 3797 3798 3799
    of interpolation can be selected by them.

    Example:

T
Tink_Y 已提交
3800
    .. code-block:: text
3801

T
Tink_Y 已提交
3802
        For scale:
3803

T
Tink_Y 已提交
3804
            if align_corners = True && out_size > 1 :
3805

T
Tink_Y 已提交
3806
              scale_factor = (in_size-1.0)/(out_size-1.0)
3807

T
Tink_Y 已提交
3808
            else:
3809

T
Tink_Y 已提交
3810
              scale_factor = float(in_size/out_size)
3811 3812


T
Tink_Y 已提交
3813
        Nearest neighbor interpolation:
3814

T
Tink_Y 已提交
3815 3816
          if:
              align_corners = False
3817

T
Tink_Y 已提交
3818 3819
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
3820

T
Tink_Y 已提交
3821 3822
              H_out = floor (H_{in} * scale_{factor})
              W_out = floor (W_{in} * scale_{factor})
3823

T
Tink_Y 已提交
3824 3825
          else:
              align_corners = True
3826

T
Tink_Y 已提交
3827 3828
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
3829

T
Tink_Y 已提交
3830 3831
              H_out = round(H_{in} * scale_{factor})
              W_out = round(W_{in} * scale_{factor})
3832

3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849
        linear interpolation:

          if:
              align_corners = False , align_mode = 0

              input : (N,C,W_in)
              output: (N,C,W_out) where:

              W_out = (W_{in}+0.5) * scale_{factor} - 0.5

          else:

              input : (N,C,W_in)
              output: (N,C,H_out,W_out) where:

              W_out = W_{in} * scale_{factor}

T
Tink_Y 已提交
3850 3851 3852 3853
        Bilinear interpolation:

          if:
              align_corners = False , align_mode = 0
3854

T
Tink_Y 已提交
3855 3856
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
3857

T
Tink_Y 已提交
3858 3859
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5
3860

T
Tink_Y 已提交
3861
          else:
3862

T
Tink_Y 已提交
3863 3864
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
3865

T
Tink_Y 已提交
3866 3867
              H_out = H_{in} * scale_{factor}
              W_out = W_{in} * scale_{factor}
3868

K
Kaipeng Deng 已提交
3869 3870 3871 3872
        Trilinear interpolation:

          if:
              align_corners = False , align_mode = 0
3873

K
Kaipeng Deng 已提交
3874 3875
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:
3876

K
Kaipeng Deng 已提交
3877 3878 3879 3880 3881 3882
              D_out = (D_{in}+0.5) * scale_{factor} - 0.5
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5


          else:
3883

K
Kaipeng Deng 已提交
3884 3885 3886 3887
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:

              D_out = D_{in} * scale_{factor}
3888

3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900
        Trilinear interpolation:
          if:
              align_corners = False , align_mode = 0
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:
              D_out = (D_{in}+0.5) * scale_{factor} - 0.5
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5
          else:
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:
              D_out = D_{in} * scale_{factor}
K
Kaipeng Deng 已提交
3901 3902
              H_out = H_{in} * scale_{factor}
              W_out = W_{in} * scale_{factor}
3903

3904

3905 3906
    For details of linear interpolation, please refer to Wikipedia:
    https://en.wikipedia.org/wiki/Linear_interpolation.
3907

3908
    For details of nearest neighbor interpolation, please refer to Wikipedia:
3909
    https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation.
3910

3911
    For details of bilinear interpolation, please refer to Wikipedia:
3912
    https://en.wikipedia.org/wiki/Bilinear_interpolation.
3913

3914
    For details of trilinear interpolation, please refer to Wikipedia:
K
Kaipeng Deng 已提交
3915
    https://en.wikipedia.org/wiki/Trilinear_interpolation.
3916

3917 3918
    For details of bicubic interpolation, please refer to Wikipedia:
    https://en.wikipedia.org/wiki/Bicubic_interpolation
3919

R
ruri 已提交
3920
    Parameters:
3921
        input (Variable): 3-D, 4-D or 5-D Tensor, its data type is float32, float64, or uint8,
3922
                          its data format is specified by :attr:`data_format`.
3923
        out_shape (list|tuple|Variable|None): Output shape of image resize
3924 3925
             layer, the shape is (out_w, ) when input is a 3-D Tensor, the shape is (out_h, out_w)
             when input is a 4-D Tensor and is (out_d, out_h, out_w) when input is a 5-D Tensor.
3926
             Default: None. If a list, each element can be an integer or a Tensor Variable of shape: [1].
3927
             If a Tensor Variable, its dimensions size should be a 1.
3928 3929 3930
        scale(float|Variable|None): The multiplier for the input height or width. At
             least one of :attr:`out_shape` or :attr:`scale` must be set.
             And :attr:`out_shape` has a higher priority than :attr:`scale`.
D
dengkaipeng 已提交
3931
             Default: None.
3932 3933
        name(str|None): A name for this layer(optional). If set None, the layer
                        will be named automatically.
3934
        resample(str): The resample method. It supports 'LINEAR', 'BICUBIC', 'BILINEAR', 'TRILINEAR'
K
Kaipeng Deng 已提交
3935
                       and 'NEAREST' currently. Default: 'BILINEAR'
3936 3937 3938
        actual_shape(Variable): An optional input to specify output shape
                                dynamically. If provided, image resize
                                according to this given shape rather than
3939
                                :attr:`out_shape` and :attr:`scale` specifying
3940 3941
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
3942 3943 3944 3945 3946
                                :attr:`out_shape` if you want to specify output
                                shape dynamically, because :attr:`actual_shape`
                                will be deprecated. When using actual_shape to
                                specify output shape, one of :attr:`out_shape`
                                and :attr:`scale` should also be set, otherwise
T
tianshuo78520a 已提交
3947
                                errors would be occurred in graph constructing stage.
3948
                                Default: None
3949 3950
        align_corners(bool) :  An optional bool, If True, the centers of the 4 corner pixels of the
                               input and output tensors are aligned, preserving the values at the
3951 3952
                               corner pixels.
                               Default: True
3953 3954
        align_mode(int)  :  An optional for linear/bilinear/trilinear interpolation. Refer to the fomula in the
                            the example code above, it can be \'0\' for src_idx = scale*(dst_indx+0.5)-0.5 ,
3955
                            can be \'1\' for src_idx = scale*dst_index.
3956
        data_format (str, optional): Specify the data format of the input, and the data format of the output
3957
            will be consistent with that of the input. An optional string from:`NCW`, `NWC`, `"NCHW"`, `"NHWC"`, `"NCDHW"`,
3958
            `"NDHWC"`. The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
3959
            `[batch_size, input_channels, input_height, input_width]`. When it is `"NCHW"`, the data is stored
3960
            in the order of: `[batch_size, input_channels, input_depth, input_height, input_width]`.
3961 3962

    Returns:
3963
        A 3-D Tensor of the shape (num_batches, channels, out_w) or (num_batches, out_w, channels),
3964 3965
        A 4-D Tensor of the shape (num_batches, channels, out_h, out_w) or (num_batches, out_h, out_w, channels),
        or 5-D Tensor of the shape (num_batches, channels, out_d, out_h, out_w) or (num_batches, out_d, out_h, out_w, channels).
F
stash  
fengjiayi 已提交
3966

3967 3968 3969
    Raises:
        TypeError: out_shape should be a list or tuple or Variable.
        TypeError: actual_shape should either be Variable or None.
3970 3971
        ValueError: The 'resample' of image_resize can only be 'LINEAR', 'BILINEAR',
                    'TRILINEAR', 'BICUBIC' or 'NEAREST' currently.
3972
        ValueError: 'LINEAR' only support 3-D tensor.
3973
        ValueError: 'BICUBIC', 'BILINEAR' and 'NEAREST' only support 4-D tensor.
K
Kaipeng Deng 已提交
3974
        ValueError: 'TRILINEAR' only support 5-D tensor.
3975
        ValueError: One of out_shape and scale must not be None.
3976
        ValueError: out_shape length should be 1 for input 3-D tensor.
K
Kaipeng Deng 已提交
3977 3978
        ValueError: out_shape length should be 2 for input 4-D tensor.
        ValueError: out_shape length should be 3 for input 5-D tensor.
D
dengkaipeng 已提交
3979
        ValueError: scale should be greater than zero.
T
tianshuo78520a 已提交
3980
        TypeError: align_corners should be a bool value
3981
        ValueError: align_mode can only be '0' or '1'
3982
        ValueError: data_format can only be 'NCW', 'NWC', 'NCHW', 'NHWC', 'NCDHW' or 'NDHWC'.
3983

3984 3985
    Examples:
        .. code-block:: python
3986

3987 3988 3989 3990 3991 3992
            #declarative mode
            import paddle
            import paddle.fluid as fluid
            import numpy as np
            paddle.enable_static()
            input = fluid.data(name="input", shape=[None,3,6,10])
R
ruri 已提交
3993

3994 3995
            #1
            output = fluid.layers.image_resize(input=input,out_shape=[12,12])
R
ruri 已提交
3996

3997 3998 3999 4000 4001
            #2
            #x = np.array([2]).astype("int32")
            #dim1 = fluid.data(name="dim1", shape=[1], dtype="int32")
            #fluid.layers.assign(input=x, output=dim1)
            #output = fluid.layers.image_resize(input=input,out_shape=[12,dim1])
R
ruri 已提交
4002

4003 4004 4005 4006 4007
            #3
            #x = np.array([3,12]).astype("int32")
            #shape_tensor = fluid.data(name="shape_tensor", shape=[2], dtype="int32")
            #fluid.layers.assign(input=x, output=shape_tensor)
            #output = fluid.layers.image_resize(input=input,out_shape=shape_tensor)
R
ruri 已提交
4008

4009 4010 4011 4012 4013
            #4
            #x = np.array([0.5]).astype("float32")
            #scale_tensor = fluid.data(name="scale", shape=[1], dtype="float32")
            #fluid.layers.assign(x,scale_tensor)
            #output = fluid.layers.image_resize(input=input,scale=scale_tensor)
R
ruri 已提交
4014

4015 4016 4017
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
4018

4019
            input_data = np.random.rand(2,3,6,10).astype("float32")
4020

4021
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
4022 4023 4024
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
4025

4026
            print(output_data[0].shape)
4027

4028 4029 4030 4031 4032 4033 4034 4035
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
4036

4037 4038
            #imperative mode
            import paddle.fluid.dygraph as dg
4039

4040 4041 4042 4043
            with dg.guard(place) as g:
                input = dg.to_variable(input_data)
                output = fluid.layers.image_resize(input=input, out_shape=[12,12])
                print(output.shape)
4044

4045
                # [2L, 3L, 12L, 12L]
4046

4047
    """
4048
    resample_methods = {
4049
        'LINEAR': 'linear',
4050
        'BILINEAR': 'bilinear',
K
Kaipeng Deng 已提交
4051
        'TRILINEAR': 'trilinear',
4052
        'NEAREST': 'nearest',
4053
        'LINEAR': 'linear',
4054
    }
4055
    resample = resample.upper()
4056 4057
    if resample not in resample_methods:
        raise ValueError(
4058
            "The 'resample' of image_resize can only be 'LINEAR', 'BILINEAR', 'TRILINEAR' "
4059 4060
            "or 'NEAREST' currently."
        )
4061
    resample_type = resample_methods[resample]
4062

4063 4064 4065
    if resample == 'LINEAR' and len(input.shape) != 3:
        raise ValueError("'LINER only support 3-D tensor.")
    elif resample in ['BILINEAR', 'NEAREST'] and len(input.shape) != 4:
K
Kaipeng Deng 已提交
4066
        raise ValueError("'BILINEAR' and 'NEAREST' only support 4-D tensor.")
4067
    elif resample == 'TRILINEAR' and len(input.shape) != 5:
K
Kaipeng Deng 已提交
4068 4069
        raise ValueError("'TRILINEAR'only support 5-D tensor.")

4070 4071 4072 4073 4074
    if not isinstance(align_corners, bool):
        raise TypeError("Attr align_corners should be a bool value")
    if align_mode != 0 and align_mode != 1:
        raise ValueError("align_mode can only be 0 or 1")

4075
    if out_shape is None and scale is None:
4076
        raise ValueError("One of out_shape and scale must not be None.")
4077
    helper = LayerHelper('{}_interp'.format(resample_type), **locals())
4078
    dtype = helper.input_dtype()
4079

4080
    if len(input.shape) == 3 and data_format not in ['NCW', 'NWC']:
4081
        raise ValueError(
4082 4083 4084 4085
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCW` or `NWC` supported for 3-D input."
        )
4086
    elif len(input.shape) == 4 and data_format not in ['NCHW', 'NHWC']:
4087
        raise ValueError(
4088 4089 4090 4091
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCHW` or `NHWC` supported for 4-D input."
        )
4092 4093
    elif len(input.shape) == 5 and data_format not in ['NCDHW', 'NDHWC']:
        raise ValueError(
4094 4095 4096 4097
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCDHW` or `NDHWC` supported for 5-D input."
        )
4098

4099
    def _is_list_or_turple_(data):
4100
        return isinstance(data, list) or isinstance(data, tuple)
4101

4102
    if data_format == 'NCHW' or data_format == 'NCDHW' or data_format == 'NCW':
4103
        data_layout = 'NCHW'
4104
    if data_format == 'NHWC' or data_format == 'NDHWC' or data_format == 'NWC':
4105 4106
        data_layout = 'NHWC'

4107
    inputs = {"X": input}
D
dengkaipeng 已提交
4108
    attrs = {
4109 4110 4111
        "out_d": -1,
        "out_h": -1,
        "out_w": -1,
D
dengkaipeng 已提交
4112 4113
        "interp_method": resample_type,
        "align_corners": align_corners,
4114
        "align_mode": align_mode,
4115
        "data_layout": data_layout,
D
dengkaipeng 已提交
4116 4117
    }

4118
    if out_shape is not None:
4119
        if isinstance(out_shape, Variable) and not _non_static_mode():
4120
            out_shape.stop_gradient = True
4121
            inputs['OutSize'] = out_shape
4122
        else:
4123 4124 4125 4126 4127 4128 4129 4130
            if _non_static_mode():
                if isinstance(out_shape, Variable):
                    out_shape = list(out_shape.numpy())
                else:
                    out_shape = list(out_shape)
                for i, dim in enumerate(out_shape):
                    if isinstance(dim, Variable):
                        out_shape[i] = dim.numpy()[0]
4131
            if not (_is_list_or_turple_(out_shape)):
D
dengkaipeng 已提交
4132
                raise TypeError(
4133 4134
                    "out_shape should be a list or tuple or Variable."
                )
4135 4136 4137 4138 4139 4140
            # Validate the shape
            contain_var = False
            for dim_idx, dim_size in enumerate(out_shape):
                if isinstance(dim_size, Variable):
                    contain_var = True
                    continue
4141 4142 4143
                assert (
                    dim_size > 0
                ), "Each dimension size given in out_shape must be greater than 0."
4144 4145 4146 4147 4148 4149 4150 4151 4152 4153

            if contain_var:
                new_size_tensor = []
                size_list = []
                for dim in out_shape:
                    if isinstance(dim, Variable):
                        dim.stop_gradient = True
                        new_size_tensor.append(dim)
                        size_list.append(-1)
                    else:
4154
                        assert isinstance(dim, int)
4155
                        temp_out = helper.create_variable_for_type_inference(
4156 4157 4158 4159 4160
                            'int32'
                        )
                        fill_constant(
                            [1], 'int32', dim, force_cpu=True, out=temp_out
                        )
4161 4162 4163 4164
                        new_size_tensor.append(temp_out)
                        size_list.append(dim)
                inputs['SizeTensor'] = new_size_tensor

4165 4166
            if len(input.shape) == 3:
                if len(out_shape) != 1:
4167 4168 4169
                    raise ValueError(
                        "out_shape length should be 1 for " "input 3-D tensor."
                    )
4170 4171 4172 4173 4174 4175
                if contain_var:
                    attrs['out_w'] = size_list[0]
                else:
                    out_shape = list(map(int, out_shape))
                    attrs['out_w'] = out_shape[0]
            elif len(input.shape) == 4:
K
Kaipeng Deng 已提交
4176
                if len(out_shape) != 2:
4177 4178 4179
                    raise ValueError(
                        "out_shape length should be 2 for " "input 4-D tensor."
                    )
4180 4181 4182 4183 4184 4185 4186
                if contain_var:
                    attrs['out_h'] = size_list[0]
                    attrs['out_w'] = size_list[1]
                else:
                    out_shape = list(map(int, out_shape))
                    attrs['out_h'] = out_shape[0]
                    attrs['out_w'] = out_shape[1]
K
Kaipeng Deng 已提交
4187 4188
            if len(input.shape) == 5:
                if len(out_shape) != 3:
4189 4190 4191
                    raise ValueError(
                        "out_shape length should be 3 for " "input 5-D tensor."
                    )
4192 4193 4194 4195 4196 4197 4198 4199 4200
                if contain_var:
                    attrs['out_d'] = size_list[0]
                    attrs['out_h'] = size_list[1]
                    attrs['out_w'] = size_list[2]
                else:
                    out_shape = list(map(int, out_shape))
                    attrs['out_d'] = out_shape[0]
                    attrs['out_h'] = out_shape[1]
                    attrs['out_w'] = out_shape[2]
4201

4202
    else:
4203 4204 4205
        if _non_static_mode() and isinstance(scale, Variable):
            scale = scale.numpy()
        elif isinstance(scale, Variable):
4206 4207
            scale.stop_gradient = True
            inputs["Scale"] = scale
4208
        elif isinstance(scale, float) or isinstance(scale, int):
4209
            if scale <= 0:
4210
                raise ValueError("Attr(scale) should be greater than zero.")
4211
            attrs['scale'] = float(scale)
4212 4213
        else:
            raise TypeError(
4214 4215
                "Attr(scale)'s type should be float, int or Variable."
            )
4216

4217
    if isinstance(actual_shape, Variable):
4218 4219 4220 4221 4222
        warnings.warn(
            "actual_shape will be deprecated, it is recommended to use "
            "out_shape instead of actual_shape to specify output shape dynamically."
        )
        actual_shape.stop_gradient = True
4223 4224 4225
        inputs["OutSize"] = actual_shape
    elif actual_shape is not None:
        raise TypeError("actual_shape should either be Variable or None.")
4226 4227 4228 4229 4230 4231 4232 4233 4234

    if _non_static_mode():
        attr_list = []
        for k, v in attrs.items():
            attr_list.append(k)
            attr_list.append(v)
        dy_attr = tuple(attr_list)

        if resample_type == "linear":
4235
            out = _legacy_C_ops.linear_interp(input, actual_shape, *dy_attr)
4236
        elif resample_type == "bilinear":
4237
            out = _legacy_C_ops.bilinear_interp(input, actual_shape, *dy_attr)
4238
        elif resample_type == "trilinear":
4239
            out = _legacy_C_ops.trilinear_interp(input, actual_shape, *dy_attr)
4240
        elif resample_type == "nearest":
4241
            out = _legacy_C_ops.nearest_interp(input, actual_shape, *dy_attr)
4242
        elif resample_type == "bicubic":
4243
            out = _legacy_C_ops.bicubic_interp(input, actual_shape, *dy_attr)
4244 4245
        return out

X
Xin Pan 已提交
4246
    out = helper.create_variable_for_type_inference(dtype)
4247 4248 4249 4250 4251 4252
    helper.append_op(
        type='{}_interp'.format(resample_type),
        inputs=inputs,
        outputs={"Out": out},
        attrs=attrs,
    )
4253
    return out
F
stash  
fengjiayi 已提交
4254 4255


4256
@templatedoc(op_type="bilinear_interp")
4257 4258 4259 4260 4261 4262 4263 4264 4265 4266
def resize_bilinear(
    input,
    out_shape=None,
    scale=None,
    name=None,
    actual_shape=None,
    align_corners=True,
    align_mode=1,
    data_format='NCHW',
):
4267
    """
4268

R
ruri 已提交
4269
    This op resizes the input by performing bilinear interpolation based on given
4270
    output shape which specified by actual_shape, out_shape and scale
4271 4272
    in priority order.

4273
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in
4274 4275
    the future and only use :attr:`out_shape` instead.

4276 4277 4278 4279
    Bilinear interpolation is an extension of linear interpolation for
    interpolating functions of two variables (e.g. H-direction and
    W-direction in this op) on a rectilinear 2D grid. The key idea is
    to perform linear interpolation first in one direction, and then
4280 4281
    again in the other direction.

4282
    For details of bilinear interpolation, please refer to Wikipedia:
4283
    https://en.wikipedia.org/wiki/Bilinear_interpolation
Y
yuyang18 已提交
4284

4285
    Align_corners and align_mode are optional parameters,the calculation
4286 4287 4288 4289
    method of interpolation can be selected by them.

    Example:

T
Tink_Y 已提交
4290
    .. code-block:: text
4291

T
Tink_Y 已提交
4292
        For scale:
4293

T
Tink_Y 已提交
4294
            if align_corners = True && out_size > 1 :
4295

T
Tink_Y 已提交
4296
              scale_factor = (in_size-1.0)/(out_size-1.0)
4297

T
Tink_Y 已提交
4298
            else:
4299

4300
              scale_factor = float(in_size/out_size)
4301

T
Tink_Y 已提交
4302 4303 4304 4305
        Bilinear interpolation:

          if:
              align_corners = False , align_mode = 0
4306

T
Tink_Y 已提交
4307 4308
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4309

T
Tink_Y 已提交
4310 4311
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5
4312

T
Tink_Y 已提交
4313
          else:
T
tink2123 已提交
4314

T
Tink_Y 已提交
4315 4316 4317 4318
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
              H_out = H_{in} * scale_{factor}
              W_out = W_{in} * scale_{factor}
4319

R
ruri 已提交
4320 4321
    Parameters:
        input(Variable): 4-D Tensor(NCHW), its data type is float32, float64, or uint8,
4322
                          its data format is specified by :attr:`data_format`.
D
dengkaipeng 已提交
4323
        out_shape(list|tuple|Variable|None): Output shape of resize bilinear
4324 4325
            layer, the shape is (out_h, out_w).Default: None. If a list, each
            element can be an integer or a Tensor Variable with shape: [1]. If a
4326
            Tensor Variable, its dimension size should be 1.
4327
        scale(float|Variable|None): The multiplier for the input height or width. At
4328 4329
             least one of :attr:`out_shape` or :attr:`scale` must be set.
             And :attr:`out_shape` has a higher priority than :attr:`scale`.
D
dengkaipeng 已提交
4330
             Default: None.
4331 4332 4333
        actual_shape(Variable): An optional input to specify output shape
                                dynamically. If provided, image resize
                                according to this given shape rather than
4334
                                :attr:`out_shape` and :attr:`scale` specifying
4335 4336
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
4337 4338 4339 4340 4341
                                :attr:`out_shape` if you want to specify output
                                shape dynamically, because :attr:`actual_shape`
                                will be deprecated. When using actual_shape to
                                specify output shape, one of :attr:`out_shape`
                                and :attr:`scale` should also be set, otherwise
T
tianshuo78520a 已提交
4342
                                errors would be occurred in graph constructing stage.
4343
                                Default: None
4344 4345
        align_corners(bool): ${align_corners_comment}
        align_mode(bool): ${align_mode_comment}
4346
        data_format (str, optional): Specify the data format of the input, and the data format of the output
4347 4348 4349
            will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`.
            The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
            `[batch_size, input_channels, input_height, input_width]`.
R
ruri 已提交
4350
        name(str, optional): The default value is None.  Normally there is no need for user to set this property.  For more information, please refer to :ref:`api_guide_Name`
Y
yuyang18 已提交
4351 4352

    Returns:
4353
        Variable: 4-D tensor(NCHW or NHWC).
4354

4355 4356
    Examples:
        .. code-block:: python
4357

4358 4359 4360 4361 4362 4363
            #declarative mode
            import paddle.fluid as fluid
            import numpy as np
            import paddle
            paddle.enable_static()
            input = fluid.data(name="input", shape=[None,3,6,10])
R
ruri 已提交
4364

4365 4366
            #1
            output = fluid.layers.resize_bilinear(input=input,out_shape=[12,12])
R
ruri 已提交
4367

4368 4369 4370 4371 4372
            #2
            #x = np.array([2]).astype("int32")
            #dim1 = fluid.data(name="dim1", shape=[1], dtype="int32")
            #fluid.layers.assign(input=x, output=dim1)
            #output = fluid.layers.resize_bilinear(input=input,out_shape=[12,dim1])
R
ruri 已提交
4373

4374 4375 4376 4377 4378
            #3
            #x = np.array([3,12]).astype("int32")
            #shape_tensor = fluid.data(name="shape_tensor", shape=[2], dtype="int32")
            #fluid.layers.assign(input=x, output=shape_tensor)
            #output = fluid.layers.resize_bilinear(input=input,out_shape=shape_tensor)
R
ruri 已提交
4379

4380 4381 4382 4383 4384
            #4
            #x = np.array([0.5]).astype("float32")
            #scale_tensor = fluid.data(name="scale", shape=[1], dtype="float32")
            #fluid.layers.assign(x,scale_tensor)
            #output = fluid.layers.resize_bilinear(input=input,scale=scale_tensor)
R
ruri 已提交
4385

4386 4387 4388
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
4389

4390
            input_data = np.random.rand(2,3,6,10).astype("float32")
4391

4392
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
4393 4394 4395
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
4396

4397
            print(output_data[0].shape)
4398

4399 4400 4401 4402 4403 4404 4405 4406
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
4407

4408 4409
            #imperative mode
            import paddle.fluid.dygraph as dg
4410

4411 4412 4413 4414
            with dg.guard(place) as g:
                input = dg.to_variable(input_data)
                output = fluid.layers.resize_bilinear(input=input, out_shape=[12,12])
                print(output.shape)
4415

4416
                # [2L, 3L, 12L, 12L]
4417

4418 4419
    """

4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'BILINEAR',
        actual_shape,
        align_corners,
        align_mode,
        data_format,
    )
4431 4432


K
Kaipeng Deng 已提交
4433
@templatedoc(op_type="trilinear_interp")
4434 4435 4436 4437 4438 4439 4440 4441 4442 4443
def resize_trilinear(
    input,
    out_shape=None,
    scale=None,
    name=None,
    actual_shape=None,
    align_corners=True,
    align_mode=1,
    data_format='NCDHW',
):
K
Kaipeng Deng 已提交
4444
    """
4445

R
ruri 已提交
4446
    This op resizes the input by performing trilinear interpolation based on given
K
Kaipeng Deng 已提交
4447 4448 4449
    output shape which specified by actual_shape, out_shape and scale
    in priority order.

4450
    **Warning:** the parameter :attr:`actual_shape` will be deprecated
4451 4452
    in the future and only use :attr:`out_shape` instead.

4453 4454 4455
    Trilinear interpolation is an extension of linear interpolation for
    interpolating functions of three variables (e.g. D-direction,
    H-direction and W-direction in this op) on a rectilinear 3D grid.
K
Kaipeng Deng 已提交
4456 4457 4458 4459 4460
    The linear interpolation is performed on three directions.

    For details of trilinear interpolation, please refer to Wikipedia:
    https://en.wikipedia.org/wiki/Trilinear_interpolation

4461
    Align_corners and align_mode are optional parameters,the calculation
K
Kaipeng Deng 已提交
4462 4463 4464 4465 4466 4467 4468
    method of interpolation can be selected by them.

    Example:

    .. code-block:: text

        For scale:
4469

K
Kaipeng Deng 已提交
4470 4471 4472
            if align_corners = True && out_size > 1 :

              scale_factor = (in_size-1.0)/(out_size-1.0)
4473

K
Kaipeng Deng 已提交
4474
            else:
4475 4476

              scale_factor = float(in_size/out_size)
K
Kaipeng Deng 已提交
4477 4478 4479 4480

        Bilinear interpolation:

          if:
4481

K
Kaipeng Deng 已提交
4482
              align_corners = False , align_mode = 0
4483

K
Kaipeng Deng 已提交
4484 4485
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:
4486

K
Kaipeng Deng 已提交
4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499
              D_out = (D_{in}+0.5) * scale_{factor} - 0.5
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5

          else:

              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:

              D_out = D_{in} * scale_{factor}
              H_out = H_{in} * scale_{factor}
              W_out = W_{in} * scale_{factor}

R
ruri 已提交
4500
    Parameters:
4501 4502
        input(${x_type}): 5-D Tensor, its data type is float32, float64, or uint8,
                          its data format is specified by :attr:`data_format`.
R
ruri 已提交
4503
        out_shape(list|tuple|Variable|None): The output shape of resized tensor, the shape is (out_d, out_h, out_w). Default: None. Every element should be an integer or a Tensor Variable with shape: [1] if it is a list. If it is a Tensor Variable, its dimension size should be 1.
4504
        scale(float|Variable|None): The multiplier for the input depth, height or width.
4505 4506
             At least one of :attr:`out_shape` or :attr:`scale` must be set.
             And :attr:`out_shape` has a higher priority than :attr:`scale`.
K
Kaipeng Deng 已提交
4507
             Default: None.
R
ruri 已提交
4508
        name(str, optional): The default value is None.  Normally there is no need for user to set this property.  For more information, please refer to :ref:`api_guide_Name`
K
Kaipeng Deng 已提交
4509 4510 4511 4512 4513 4514
        actual_shape(Variable): An optional input to specify output shape
                                dynamically. If provided, image resize
                                according to this given shape rather than
                                :attr:`out_shape` and :attr:`scale` specifying
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
4515 4516 4517 4518 4519
                                :attr:`out_shape` if you want to specify output
                                shape dynamically, because :attr:`actual_shape`
                                will be deprecated. When using actual_shape to
                                specify output shape, one of :attr:`out_shape`
                                and :attr:`scale` should also be set, otherwise
T
tianshuo78520a 已提交
4520
                                errors would be occurred in graph constructing stage.
K
Kaipeng Deng 已提交
4521 4522 4523
                                Default: None
        align_corners(bool): ${align_corners_comment}
        align_mode(bool): ${align_mode_comment}
4524
        data_format (str, optional): Specify the data format of the input, and the data format of the output
4525 4526 4527
            will be consistent with that of the input. An optional string from: `"NCDHW"`, `"NDHWC"`.
            The default is `"NCDHW"`. When it is `"NCDHW"`, the data is stored in the order of:
            `[batch_size, input_channels, input_depth, input_height, input_width]`.
K
Kaipeng Deng 已提交
4528 4529

    Returns:
4530
        Variable: A 5-D Tensor(NCDHW or NDHWC)
K
Kaipeng Deng 已提交
4531 4532 4533

    Examples:
        .. code-block:: python
4534

4535 4536 4537 4538 4539 4540
            #declarative mode
            import paddle.fluid as fluid
            import paddle
            import numpy as np
            paddle.enable_static()
            input = fluid.data(name="input", shape=[None,3,6,8,10])
R
ruri 已提交
4541

4542 4543
            #1
            output = fluid.layers.resize_trilinear(input=input,out_shape=[12,12,12])
R
ruri 已提交
4544

4545 4546 4547 4548 4549
            #2
            #x = np.array([2]).astype("int32")
            #dim1 = fluid.data(name="dim1", shape=[1], dtype="int32")
            #fluid.layers.assign(input=x, output=dim1)
            #output = fluid.layers.resize_trilinear(input=input,out_shape=[12,dim1,4])
R
ruri 已提交
4550

4551 4552 4553 4554 4555
            #3
            #x = np.array([3,12,12]).astype("int32")
            #shape_tensor = fluid.data(name="shape_tensor", shape=[3], dtype="int32")
            #fluid.layers.assign(input=x, output=shape_tensor)
            #output = fluid.layers.resize_trilinear(input=input,out_shape=shape_tensor)
R
ruri 已提交
4556

4557 4558 4559 4560 4561
            #4
            #x = np.array([0.5]).astype("float32")
            #scale_tensor = fluid.data(name="scale", shape=[1], dtype="float32")
            #fluid.layers.assign(x,scale_tensor)
            #output = fluid.layers.resize_trilinear(input=input,scale=scale_tensor)
R
ruri 已提交
4562

4563 4564 4565
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
4566

4567
            input_data = np.random.rand(2,3,6,8,10).astype("float32")
K
Kaipeng Deng 已提交
4568

4569
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
4570 4571 4572
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
4573

4574
            print(output_data[0].shape)
R
ruri 已提交
4575

4576 4577 4578 4579 4580 4581 4582 4583
            #1
            # (2, 3, 12, 12, 12)
            #2
            # (2, 3, 12, 2, 4)
            #3
            # (2, 3, 3, 12, 12)
            #4
            # (2, 3, 3, 4, 5)
R
ruri 已提交
4584

4585 4586
            #imperative mode
            import paddle.fluid.dygraph as dg
4587

4588 4589 4590 4591
            with dg.guard(place) as g:
                input = dg.to_variable(input_data)
                output = fluid.layers.resize_trilinear(input=input, out_shape=[12,12,12])
                print(output.shape)
4592

4593
                # [2L, 3L, 12L, 12L, 12L]
4594 4595 4596



K
Kaipeng Deng 已提交
4597 4598
    """

4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'TRILINEAR',
        actual_shape,
        align_corners,
        align_mode,
        data_format,
    )
K
Kaipeng Deng 已提交
4610 4611


4612
@templatedoc(op_type="nearest_interp")
4613 4614 4615 4616 4617 4618 4619 4620 4621
def resize_nearest(
    input,
    out_shape=None,
    scale=None,
    name=None,
    actual_shape=None,
    align_corners=True,
    data_format='NCHW',
):
4622
    """
4623

R
ruri 已提交
4624
    This op resizes the input by performing nearest neighbor interpolation in both the
4625
    height direction and the width direction based on given output shape
4626
    which is specified by actual_shape, out_shape and scale in priority order.
4627

4628
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in the
4629 4630
    future and only use :attr:`out_shape` instead.

4631 4632
    Example:

T
Tink_Y 已提交
4633 4634 4635
    .. code-block:: text

        For scale:
4636

T
Tink_Y 已提交
4637 4638
            if align_corners = True && out_size > 1 :
              scale_factor = (in_size-1.0)/(out_size-1.0)
4639

T
Tink_Y 已提交
4640
            else:
4641

T
Tink_Y 已提交
4642
              scale_factor = float(in_size/out_size)
4643

T
Tink_Y 已提交
4644
        Nearest neighbor interpolation:
4645

T
Tink_Y 已提交
4646 4647
          if:
              align_corners = False
4648

T
Tink_Y 已提交
4649 4650
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4651

T
Tink_Y 已提交
4652 4653
              H_out = floor(H_{in} * scale_{factor})
              W_out = floor(W_{in} * scale_{factor})
4654

T
Tink_Y 已提交
4655 4656
          else:
              align_corners = True
4657

T
Tink_Y 已提交
4658 4659
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4660

T
Tink_Y 已提交
4661 4662
              H_out = round(H_{in} * scale_{factor})
              W_out = round(W_{in} * scale_{factor})
4663 4664


4665
    For details of nearest neighbor interpolation, please refer to Wikipedia:
4666
    https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation
Y
yuyang18 已提交
4667

R
ruri 已提交
4668
    Parameters:
4669 4670
        input(${x_type}): 4-D Tensor, its data type is float32, float64, or uint8,
                          its data format is specified by :attr:`data_format`.
R
ruri 已提交
4671
        out_shape(list|tuple|Variable|None): The output shape of resized tensor, the shape is (out_h, out_w). Default: None. Every element should be an integer or a tensor Variable with shape: [1] if it is a list. If it is a tensor Variable, its dimension size should be 1.
4672
        scale(float|Variable|None): The multiplier for the input height or width. At
4673 4674 4675
             least one of :attr:`out_shape` or :attr:`scale` must be set.
             And :attr:`out_shape` has a higher priority than :attr:`scale`.
             Default: None.
R
ruri 已提交
4676
        name(str, optional): The default value is None.  Normally there is no need for user to set this property.  For more information, please refer to :ref:`api_guide_Name`
4677
        actual_shape(Variable): An optional input to specify output shape
4678 4679
                                dynamically. If provided, image resize
                                according to this given shape rather than
4680
                                :attr:`out_shape` and :attr:`scale` specifying
4681 4682
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
4683 4684 4685 4686 4687
                                :attr:`out_shape` if you want to specify output
                                shape dynamically, because :attr:`actual_shape`
                                will be deprecated. When using actual_shape to
                                specify output shape, one of :attr:`out_shape`
                                and :attr:`scale` should also be set, otherwise
T
tianshuo78520a 已提交
4688
                                errors would be occurred in graph constructing stage.
4689
                                Default: None
4690
        align_corners(bool): ${align_corners_comment}
4691
        data_format (str, optional): Specify the data format of the input, and the data format of the output
4692 4693 4694
            will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`.
            The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
            `[batch_size, input_channels, input_height, input_width]`.
Y
yuyang18 已提交
4695 4696

    Returns:
4697
        Variable: 4-D tensor(NCHW or NHWC).
4698 4699 4700

    Examples:
        .. code-block:: python
4701

4702 4703 4704 4705 4706
            #declarative mode
            import paddle.fluid as fluid
            import numpy as np
            import paddle
            paddle.enable_static()
4707

4708
            input = fluid.data(name="input", shape=[None,3,6,10])
R
ruri 已提交
4709

4710 4711
            #1
            output = fluid.layers.resize_nearest(input=input,out_shape=[12,12])
R
ruri 已提交
4712

4713 4714 4715 4716 4717
            #2
            #x = np.array([2]).astype("int32")
            #dim1 = fluid.data(name="dim1", shape=[1], dtype="int32")
            #fluid.layers.assign(input=x, output=dim1)
            #output = fluid.layers.resize_nearest(input=input,out_shape=[12,dim1])
R
ruri 已提交
4718

4719 4720 4721 4722 4723
            #3
            #x = np.array([3,12]).astype("int32")
            #shape_tensor = fluid.data(name="shape_tensor", shape=[2], dtype="int32")
            #fluid.layers.assign(input=x, output=shape_tensor)
            #output = fluid.layers.resize_nearest(input=input,out_shape=shape_tensor)
R
ruri 已提交
4724

4725 4726 4727 4728 4729
            #4
            #x = np.array([0.5]).astype("float32")
            #scale_tensor = fluid.data(name="scale", shape=[1], dtype="float32")
            #fluid.layers.assign(x,scale_tensor)
            #output = fluid.layers.resize_nearest(input=input,scale=scale_tensor)
R
ruri 已提交
4730

4731 4732 4733
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
4734

4735
            input_data = np.random.rand(2,3,6,10).astype("float32")
4736

4737
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
4738 4739 4740
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
4741

4742
            print(output_data[0].shape)
R
ruri 已提交
4743

4744 4745 4746 4747 4748 4749 4750 4751
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
4752

4753 4754
            #imperative mode
            import paddle.fluid.dygraph as dg
4755

4756 4757 4758 4759
            with dg.guard(place) as g:
                input = dg.to_variable(input_data)
                output = fluid.layers.resize_nearest(input=input, out_shape=[12,12])
                print(output.shape)
R
ruri 已提交
4760

4761
                # [2L, 3L, 12L, 12L]
4762 4763 4764



4765 4766
    """

4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'NEAREST',
        actual_shape,
        align_corners,
        align_mode=1,
        data_format=data_format,
    )
4778 4779


4780
@deprecated(since="2.0.0", update_to="paddle.nn.functional.relu")
4781
def relu(x, name=None):
W
wanghaoshuang 已提交
4782
    """
Z
zhupengyang 已提交
4783
    ${comment}
W
wanghaoshuang 已提交
4784 4785

    Args:
Z
zhupengyang 已提交
4786 4787 4788 4789
        x(Variable): ${x_comment}
        name(str, optional): The default value is None. Normally there is no
            need for user to set this property. For more information, please
            refer to :ref:`api_guide_Name`.
W
wanghaoshuang 已提交
4790 4791

    Returns:
Z
zhupengyang 已提交
4792
        Variable: ${out_comment}
W
wanghaoshuang 已提交
4793 4794 4795 4796 4797

    Examples:

        .. code-block:: python

4798
            import paddle.fluid as fluid
Z
zhupengyang 已提交
4799 4800 4801 4802 4803 4804 4805
            import numpy as np
            in1 = np.array([[-1,0],[1,2.6]])
            with fluid.dygraph.guard():
                x1 = fluid.dygraph.to_variable(in1)
                out1 = fluid.layers.relu(x1)
                print(out1.numpy())
                # [[0.  0. ]
4806
                #  [1.  2.6]]"""
4807 4808

    if in_dygraph_mode():
W
wanghuancoder 已提交
4809
        return _C_ops.relu(x)
4810 4811
    if _in_legacy_dygraph():
        return _legacy_C_ops.relu(x)
4812

4813 4814
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'relu')

4815
    inputs = {'X': [x]}
W
wanghaoshuang 已提交
4816
    helper = LayerHelper('relu', **locals())
W
wanghaoshuang 已提交
4817
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
4818
    out = helper.create_variable_for_type_inference(dtype)
4819 4820 4821
    helper.append_op(
        type="relu", inputs={"X": helper.input('x')}, outputs={"Out": out}
    )
W
wanghaoshuang 已提交
4822
    return out
4823 4824


G
fix  
gongweibao 已提交
4825 4826 4827
from paddle.fluid.framework import convert_np_dtype_to_dtype_


4828
@deprecated(since="2.0.0", update_to="paddle.normal")
G
gongweibao 已提交
4829
@templatedoc()
4830 4831 4832
def gaussian_random(
    shape, mean=0.0, std=1.0, seed=0, dtype='float32', name=None
):
G
fix  
gongweibao 已提交
4833
    """
4834 4835
    This OP returns a Tensor filled with random values sampled from a Gaussian
    distribution, with ``shape`` and ``dtype``.
G
fix  
gongweibao 已提交
4836 4837

    Args:
4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852
        shape(list|tuple|Tensor): The shape of the output Tensor. If ``shape``
            is a list or tuple, the elements of it should be integers or Tensors
            (with the shape [1], and the data type int32 or int64). If ``shape``
            is a Tensor, it should be a 1-D Tensor(with the data type int32 or
            int64).
        mean(float|int, optional): Mean of the output tensor, default is 0.0.
        std(float|int, optional): Standard deviation of the output tensor, default
            is 1.0.
        seed(int, optional): ${seed_comment}
        dtype(str|np.dtype|core.VarDesc.VarType, optional): The data type of
            the output Tensor. Supported data types: float32, float64.
            Default is float32.
        name(str, optional): The default value is None. Normally there is no
            need for user to set this property. For more information, please
            refer to :ref:`api_guide_Name`.
G
fix  
gongweibao 已提交
4853 4854

    Returns:
4855 4856
        Tensor: A Tensor filled with random values sampled from a Gaussian
        distribution, with ``shape`` and ``dtype``.
G
fix  
gongweibao 已提交
4857

4858
    Examples:
4859
       .. code-block:: python
4860

4861
            import paddle
4862
            import paddle.fluid as fluid
4863
            paddle.enable_static()
4864 4865

            # example 1:
4866
            # attr shape is a list which doesn't contain Tensor.
4867
            result_1 = fluid.layers.gaussian_random(shape=[3, 4])
4868 4869 4870
            # [[-0.31261674,  1.8736548,  -0.6274357,   0.96988016],
            #  [-0.12294637,  0.9554768,   1.5690808,  -1.2894802 ],
            #  [-0.60082096, -0.61138713,  1.5345167,  -0.21834975]]
4871 4872

            # example 2:
4873 4874 4875
            # attr shape is a list which contains Tensor.
            dim_1 = fluid.layers.fill_constant([1], "int64", 2)
            dim_2 = fluid.layers.fill_constant([1], "int32", 3)
4876
            result_2 = fluid.layers.gaussian_random(shape=[dim_1, dim_2])
4877 4878
            # [[ 0.51398206, -0.3389769,   0.23597084],
            #  [ 1.0388143,  -1.2015356,  -1.0499583 ]]
4879 4880

            # example 3:
4881
            # attr shape is a Tensor, the data type must be int64 or int32.
4882 4883
            var_shape = fluid.data(name='var_shape', shape=[2], dtype="int64")
            result_3 = fluid.layers.gaussian_random(var_shape)
4884 4885 4886 4887
            # if var_shape's value is [2, 3]
            # result_3 is:
            # [[-0.12310527,  0.8187662,   1.923219  ]
            #  [ 0.70721835,  0.5210541,  -0.03214082]]
4888

4889
       .. code-block:: python
4890

4891 4892
           # declarative mode
           # required: skiptest
4893 4894
           import numpy as np
           from paddle import fluid
4895

4896
           x = fluid.layers.gaussian_random((2, 3), std=2., seed=10)
4897

4898 4899 4900 4901
           place = fluid.CPUPlace()
           exe = fluid.Executor(place)
           start = fluid.default_startup_program()
           main = fluid.default_main_program()
4902

4903 4904
           exe.run(start)
           x_np, = exe.run(main, feed={}, fetch_list=[x])
4905

4906 4907 4908 4909 4910 4911 4912 4913 4914 4915
           x_np
           # array([[2.3060477, 2.676496 , 3.9911983],
           #        [0.9990833, 2.8675377, 2.2279181]], dtype=float32)

       .. code-block:: python

           # imperative mode
           import numpy as np
           from paddle import fluid
           import paddle.fluid.dygraph as dg
4916

4917 4918 4919
           place = fluid.CPUPlace()
           with dg.guard(place) as g:
               x = fluid.layers.gaussian_random((2, 4), mean=2., dtype="float32", seed=10)
4920
               x_np = x.numpy()
4921 4922 4923
           x_np
           # array([[2.3060477 , 2.676496  , 3.9911983 , 0.9990833 ],
           #        [2.8675377 , 2.2279181 , 0.79029655, 2.8447366 ]], dtype=float32)
G
fix  
gongweibao 已提交
4924
    """
4925 4926
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
4927

4928 4929 4930
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
        place = _current_expected_place()
4931
        return _C_ops.gaussian(
4932 4933
            shape, float(mean), float(std), seed, dtype, place
        )
4934 4935

    if _in_legacy_dygraph():
4936
        shape = utils.convert_shape_to_list(shape)
4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948
        return _legacy_C_ops.gaussian_random(
            'shape',
            shape,
            'mean',
            float(mean),
            'std',
            float(std),
            'seed',
            seed,
            'dtype',
            dtype,
        )
4949 4950 4951

    check_type(shape, 'shape', (list, tuple, Variable), 'gaussian_random/randn')
    check_dtype(dtype, 'dtype', ['float32', 'float64'], 'gaussian_random/randn')
4952 4953

    inputs = {}
4954 4955 4956 4957
    attrs = {
        'mean': mean,
        'std': std,
        'seed': seed,
4958
        'dtype': dtype,
4959
        'use_mkldnn': False,
4960
    }
4961 4962 4963
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='gaussian_random/randn'
    )
4964

4965 4966
    helper = LayerHelper('gaussian_random', **locals())
    out = helper.create_variable_for_type_inference(dtype)
4967 4968 4969
    helper.append_op(
        type='gaussian_random', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
G
fix  
gongweibao 已提交
4970 4971 4972 4973

    return out


G
gongweibao 已提交
4974
@templatedoc()
G
fix  
gongweibao 已提交
4975
def sampling_id(x, min=0.0, max=1.0, seed=0, dtype='float32'):
G
fix  
gongweibao 已提交
4976
    """
R
ruri 已提交
4977
    This op is used for sampling id from multinomial distribution from the input, sampling one id for one sample.
G
fix  
gongweibao 已提交
4978

R
ruri 已提交
4979 4980 4981 4982
    Parameters:
        x (Variable): 2-D tensor, [batch_size, input_feature_dimensions]
        min (Float): minimum , default 0.0.
        max (Float): maximum, default 1.0.
4983
        seed (Float): Random seed, default 0. if seed is not 0, will generate same number every time.
G
fix  
gongweibao 已提交
4984
        dtype(np.dtype|core.VarDesc.VarType|str): The type of output data : float32, float_16, int etc
G
fix  
gongweibao 已提交
4985 4986

    Returns:
R
ruri 已提交
4987
        Variable: sampling tensor.
G
fix  
gongweibao 已提交
4988

4989 4990 4991
    Examples:
        .. code-block:: python

4992
            import paddle.fluid as fluid
R
ruri 已提交
4993
            x = fluid.data(
4994 4995
                name="X",
                shape=[13, 11],
R
ruri 已提交
4996
                dtype='float32')
4997

Y
Yibing Liu 已提交
4998
            out = fluid.layers.sampling_id(x)
G
fix  
gongweibao 已提交
4999 5000 5001
    """

    helper = LayerHelper('sampling_id', **locals())
X
Xin Pan 已提交
5002
    out = helper.create_variable_for_type_inference(dtype)
5003 5004 5005 5006 5007 5008
    helper.append_op(
        type='sampling_id',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'min': min, 'max': max, 'seed': seed},
    )
G
fix  
gongweibao 已提交
5009 5010 5011 5012 5013 5014

    return out


def shape(input):
    """
5015
    :alias_main: paddle.shape
5016 5017
        :alias: paddle.shape,paddle.tensor.shape,paddle.tensor.attribute.shape
        :old_api: paddle.fluid.layers.shape
5018

C
chengduozh 已提交
5019 5020
    **Shape Layer**

C
fix doc  
chengduozh 已提交
5021
    Get the shape of the input.
G
fix  
gongweibao 已提交
5022

5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039
    .. code-block:: text

        Case1:
            Given N-D Tensor:
                input = [ [1, 2, 3, 4], [5, 6, 7, 8] ]

            Then:
                input.shape = [2, 4]

        Case2:
            Given SelectedRows:
                input.rows = [0, 4, 19]
                input.height = 20
                input.value = [ [1, 2], [3, 4], [5, 6] ]  # inner tensor
            Then:
                input.shape = [3, 2]

G
fix  
gongweibao 已提交
5040
    Args:
5041
        input (Variable): The input can be N-D Tensor or SelectedRows with data type bool, float16, float32, float64, int32, int64.
5042
                          If input variable is type of SelectedRows, returns the shape of it's inner tensor.
G
fix  
gongweibao 已提交
5043 5044

    Returns:
5045
        Variable (Tensor): The shape of the input variable.
G
fix  
gongweibao 已提交
5046

5047 5048 5049
    Examples:
        .. code-block:: python

5050
            import paddle.fluid as fluid
5051
            import numpy as np
W
Wilber 已提交
5052 5053
            import paddle
            paddle.enable_static()
5054

5055
            inputs = fluid.data(name="x", shape=[3, 100, 100], dtype="float32")
5056 5057 5058 5059 5060 5061 5062 5063 5064
            output = fluid.layers.shape(inputs)

            exe = fluid.Executor(fluid.CPUPlace())
            exe.run(fluid.default_startup_program())

            img = np.ones((3, 100, 100)).astype(np.float32)

            res = exe.run(fluid.default_main_program(), feed={'x':img}, fetch_list=[output])
            print(res) # [array([  3, 100, 100], dtype=int32)]
G
fix  
gongweibao 已提交
5065
    """
5066
    if in_dygraph_mode():
5067
        out = _C_ops.shape(input)
5068 5069 5070
        out.stop_gradient = True
        return out
    if _in_legacy_dygraph():
5071
        out = _legacy_C_ops.shape(input)
W
Wilber 已提交
5072 5073 5074
        out.stop_gradient = True
        return out

5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089
    check_variable_and_dtype(
        input,
        'input',
        [
            'bool',
            'float16',
            'float32',
            'float64',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        'shape',
    )
G
fix  
gongweibao 已提交
5090
    helper = LayerHelper('shape', **locals())
5091
    out = helper.create_variable_for_type_inference(dtype='int32')
5092 5093 5094 5095 5096 5097
    helper.append_op(
        type='shape',
        inputs={'Input': input},
        outputs={'Out': out},
        stop_gradient=True,
    )
G
fix  
gongweibao 已提交
5098 5099

    return out
G
merge  
gongweibao 已提交
5100 5101


S
sneaxiy 已提交
5102 5103 5104 5105
def _elementwise_op(helper):
    op_type = helper.layer_type
    x = helper.kwargs.get('x', None)
    y = helper.kwargs.get('y', None)
X
Xin Pan 已提交
5106

S
sneaxiy 已提交
5107 5108
    assert x is not None, 'x cannot be None in {}'.format(op_type)
    assert y is not None, 'y cannot be None in {}'.format(op_type)
5109
    check_variable_and_dtype(
5110 5111 5112 5113 5114
        x,
        'x',
        ['float16', 'uint16', 'float32', 'float64', 'int32', 'int64'],
        op_type,
    )
5115
    check_variable_and_dtype(
5116 5117 5118 5119 5120
        y,
        'y',
        ['float16', 'uint16', 'float32', 'float64', 'int32', 'int64'],
        op_type,
    )
5121

S
sneaxiy 已提交
5122 5123
    axis = helper.kwargs.get('axis', -1)
    use_mkldnn = helper.kwargs.get('use_mkldnn', False)
S
sneaxiy 已提交
5124
    name = helper.kwargs.get('name', None)
5125
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
S
sneaxiy 已提交
5126

5127 5128 5129 5130 5131 5132
    helper.append_op(
        type=op_type,
        inputs={'X': x, 'Y': y},
        outputs={'Out': out},
        attrs={'axis': axis, 'use_mkldnn': use_mkldnn},
    )
S
sneaxiy 已提交
5133 5134 5135
    return helper.append_activation(out)


X
Xin Pan 已提交
5136
def elementwise_add(x, y, axis=-1, act=None, name=None):
5137
    """
5138

5139
    Examples:
5140

5141
        .. code-block:: python
5142

5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155
            import paddle.fluid as fluid
            import numpy as np
            import paddle
            def gen_data():
                return {
                    "x": np.array([2, 3, 4]).astype('float32'),
                    "y": np.array([1, 5, 2]).astype('float32')
                }
            paddle.enable_static()
            x = fluid.data(name="x", shape=[3], dtype='float32')
            y = fluid.data(name="y", shape=[3], dtype='float32')
            z = fluid.layers.elementwise_add(x, y)
            # z = x + y
5156

5157 5158 5159 5160
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5161

5162
            print(z_value) # [3., 8., 6.]
5163 5164


5165
        .. code-block:: python
5166

5167 5168 5169
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5170

5171 5172 5173 5174 5175 5176 5177 5178 5179 5180
            def gen_data():
                return {
                    "x": np.ones((2, 3, 4, 5)).astype('float32'),
                    "y": np.zeros((3, 4)).astype('float32')
                }
            paddle.enable_static()
            x = fluid.data(name="x", shape=[2,3,4,5], dtype='float32')
            y = fluid.data(name="y", shape=[3,4], dtype='float32')
            z = fluid.layers.elementwise_add(x, y, axis=1)
            # z = x + y
5181

5182 5183
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5184

5185 5186
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5187

5188
            print(z_value) # z.shape=[2,3,4,5]
5189 5190


5191
        ..  code-block:: python
5192

5193 5194 5195
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5196

5197 5198 5199 5200 5201 5202 5203 5204 5205 5206
            def gen_data():
                return {
                    "x": np.random.randint(1, 5, size=[2, 3, 4, 5]).astype('float32'),
                    "y": np.random.randint(1, 5, size=[5]).astype('float32')
                }
            paddle.enable_static()
            x = fluid.data(name="x", shape=[2,3,4,5], dtype='float32')
            y = fluid.data(name="y", shape=[5], dtype='float32')
            z = fluid.layers.elementwise_add(x, y, axis=3)
            # z = x + y
5207

5208 5209
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5210

5211 5212 5213
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
5214 5215

    """
J
Jiabin Yang 已提交
5216
    if _non_static_mode():
5217
        return _elementwise_op_in_dygraph(
5218 5219 5220 5221 5222
            x,
            y,
            axis=axis,
            act=act,
            op_name='elementwise_add',
5223 5224
            use_mkldnn=_global_flags()["FLAGS_use_mkldnn"],
        )
5225

S
sneaxiy 已提交
5226 5227 5228
    return _elementwise_op(LayerHelper('elementwise_add', **locals()))


5229
@deprecated(since="2.0.0", update_to="paddle.divide")
X
Xin Pan 已提交
5230
def elementwise_div(x, y, axis=-1, act=None, name=None):
5231
    """
5232

5233
    Examples:
5234

5235
        .. code-block:: python
5236

5237 5238 5239
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5240

5241 5242 5243 5244 5245 5246 5247 5248 5249 5250
            def gen_data():
                return {
                    "x": np.array([2, 3, 4]).astype('float32'),
                    "y": np.array([1, 5, 2]).astype('float32')
                }
            paddle.enable_static()
            x = fluid.data(name="x", shape=[3], dtype='float32')
            y = fluid.data(name="y", shape=[3], dtype='float32')
            z = fluid.layers.elementwise_div(x, y)
            # z = x / y
5251

5252 5253 5254 5255
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5256

5257
            print(z_value) # [2., 0.6, 2.]
5258 5259


5260
        .. code-block:: python
5261

5262 5263 5264
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5265

5266 5267 5268 5269 5270 5271 5272 5273 5274 5275
            def gen_data():
                return {
                    "x": np.ones((2, 3, 4, 5)).astype('float32'),
                    "y": np.zeros((3, 4)).astype('float32')
                }
            paddle.enable_static()
            x = fluid.data(name="x", shape=[2,3,4,5], dtype='float32')
            y = fluid.data(name="y", shape=[3,4], dtype='float32')
            z = fluid.layers.elementwise_div(x, y, axis=1)
            # z = x / y
5276

5277 5278
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5279

5280 5281
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5282

5283
            print(z_value) # z.shape=[2,3,4,5]
5284 5285


5286
        ..  code-block:: python
5287

5288 5289 5290
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5291

5292 5293 5294 5295 5296 5297 5298 5299 5300 5301
            def gen_data():
                return {
                    "x": np.random.randint(1, 5, size=[2, 3, 4, 5]).astype('float32'),
                    "y": np.random.randint(1, 5, size=[5]).astype('float32')
                }
            paddle.enable_static()
            x = fluid.data(name="x", shape=[2,3,4,5], dtype='float32')
            y = fluid.data(name="y", shape=[5], dtype='float32')
            z = fluid.layers.elementwise_div(x, y, axis=3)
            # z = x / y
5302

5303 5304
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5305

5306 5307 5308
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
5309 5310

    """
J
Jiabin Yang 已提交
5311
    if _non_static_mode():
5312 5313 5314
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_div'
        )
5315

S
sneaxiy 已提交
5316 5317 5318
    return _elementwise_op(LayerHelper('elementwise_div', **locals()))


X
Xin Pan 已提交
5319
def elementwise_sub(x, y, axis=-1, act=None, name=None):
5320
    """
5321

5322
    Examples:
5323

5324
        .. code-block:: python
5325

5326 5327 5328
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5329

5330 5331 5332 5333 5334 5335 5336 5337 5338 5339
            def gen_data():
                return {
                    "x": np.array([2, 3, 4]).astype('float32'),
                    "y": np.array([1, 5, 2]).astype('float32')
                }
            paddle.enable_static()
            x = fluid.data(name="x", shape=[3], dtype='float32')
            y = fluid.data(name="y", shape=[3], dtype='float32')
            z = fluid.layers.elementwise_sub(x, y)
            # z = x - y
5340

5341 5342 5343 5344
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5345

5346
            print(z_value) # [1., -2., 2.]
5347 5348


5349
        .. code-block:: python
5350

5351 5352 5353
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5354

5355 5356 5357 5358 5359 5360 5361 5362 5363 5364
            def gen_data():
                return {
                    "x": np.ones((2, 3, 4, 5)).astype('float32'),
                    "y": np.zeros((3, 4)).astype('float32')
                }
            paddle.enable_static()
            x = fluid.data(name="x", shape=[2,3,4,5], dtype='float32')
            y = fluid.data(name="y", shape=[3,4], dtype='float32')
            z = fluid.layers.elementwise_sub(x, y, axis=1)
            # z = x - y
5365

5366 5367
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5368

5369 5370
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5371

5372
            print(z_value) # z.shape=[2,3,4,5]
5373 5374


5375
        ..  code-block:: python
5376

5377 5378 5379
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5380

5381 5382 5383 5384 5385 5386 5387 5388 5389 5390
            def gen_data():
                return {
                    "x": np.random.randint(1, 5, size=[2, 3, 4, 5]).astype('float32'),
                    "y": np.random.randint(1, 5, size=[5]).astype('float32')
                }
            paddle.enable_static()
            x = fluid.data(name="x", shape=[2,3,4,5], dtype='float32')
            y = fluid.data(name="y", shape=[5], dtype='float32')
            z = fluid.layers.elementwise_sub(x, y, axis=3)
            # z = x - y
5391

5392 5393
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5394

5395 5396 5397
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
5398 5399

    """
J
Jiabin Yang 已提交
5400
    if _non_static_mode():
5401 5402 5403
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_sub'
        )
5404

S
sneaxiy 已提交
5405 5406 5407
    return _elementwise_op(LayerHelper('elementwise_sub', **locals()))


5408
@deprecated(since="2.0.0", update_to="paddle.multiply")
X
Xin Pan 已提交
5409
def elementwise_mul(x, y, axis=-1, act=None, name=None):
5410
    """
5411

5412
    Examples:
5413

5414
        .. code-block:: python
5415

5416 5417 5418
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5419

5420 5421 5422 5423 5424 5425 5426 5427 5428 5429
            def gen_data():
                return {
                    "x": np.array([2, 3, 4]).astype('float32'),
                    "y": np.array([1, 5, 2]).astype('float32')
                }
            paddle.enable_static()
            x = fluid.data(name="x", shape=[3], dtype='float32')
            y = fluid.data(name="y", shape=[3], dtype='float32')
            z = fluid.layers.elementwise_mul(x, y)
            # z = x * y
5430

5431 5432 5433 5434
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5435

5436
            print(z_value) # [2., 15., 8.]
5437 5438


5439
        .. code-block:: python
5440

5441 5442 5443
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5444

5445 5446 5447 5448 5449 5450 5451 5452 5453 5454
            def gen_data():
                return {
                    "x": np.ones((2, 3, 4, 5)).astype('float32'),
                    "y": np.zeros((3, 4)).astype('float32')
                }
            paddle.enable_static()
            x = fluid.data(name="x", shape=[2,3,4,5], dtype='float32')
            y = fluid.data(name="y", shape=[3,4], dtype='float32')
            z = fluid.layers.elementwise_mul(x, y, axis=1)
            # z = x * y
5455

5456 5457
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5458

5459 5460
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5461

5462
            print(z_value) # z.shape=[2,3,4,5]
5463 5464


5465
        ..  code-block:: python
5466

5467 5468 5469
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5470

5471 5472 5473 5474 5475 5476 5477 5478 5479 5480
            def gen_data():
                return {
                    "x": np.random.randint(1, 5, size=[2, 3, 4, 5]).astype('float32'),
                    "y": np.random.randint(1, 5, size=[5]).astype('float32')
                }
            paddle.enable_static()
            x = fluid.data(name="x", shape=[2,3,4,5], dtype='float32')
            y = fluid.data(name="y", shape=[5], dtype='float32')
            z = fluid.layers.elementwise_mul(x, y, axis=3)
            # z = x * y
5481

5482 5483
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5484

5485 5486 5487
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
5488

5489
    """
J
Jiabin Yang 已提交
5490
    if _non_static_mode():
5491 5492 5493
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_mul'
        )
5494

S
sneaxiy 已提交
5495 5496 5497 5498
    return _elementwise_op(LayerHelper('elementwise_mul', **locals()))


for func in [
5499 5500 5501 5502
    elementwise_add,
    elementwise_div,
    elementwise_sub,
    elementwise_mul,
5503 5504
]:
    op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
5505 5506

    # insert the c++ doc string on top of python doc string
5507 5508 5509 5510 5511
    func.__doc__ = (
        _generate_doc_string_(
            op_proto,
            additional_args_lines=[
                "axis (int32, optional): If X.dimension != Y.dimension, \
5512 5513
            Y.dimension must be a subsequence of x.dimension. \
            And axis is the start dimension index for broadcasting Y onto X. ",
5514
                "act (string, optional): Activation applied to the output. \
5515
            Default is None. Details: :ref:`api_guide_activations_en` ",
5516
                "name (string, optional): Name of the output. \
5517
            Default is None. It's used to print debug info for developers. Details: \
5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533
            :ref:`api_guide_Name` ",
            ],
            skip_attrs_set={
                "x_data_format",
                "y_data_format",
                "axis",
                "use_quantizer",
                "mkldnn_data_type",
                "Scale_x",
                "Scale_y",
                "Scale_out",
            },
        )
        + """\n"""
        + str(func.__doc__)
    )
5534

5535 5536 5537
    doc_list = func.__doc__.splitlines()

    for idx, val in enumerate(doc_list):
5538 5539 5540 5541 5542
        if (
            val.startswith("Warning: ")
            and val.endswith(" instead.")
            and "and will be removed in future versions." in val
        ):
5543 5544 5545 5546
            doc_list.insert(0, doc_list.pop(idx))
            func.__doc__ = "\n" + "\n".join(i for i in doc_list)
            break

5547
for func in []:
S
sneaxiy 已提交
5548 5549 5550 5551
    op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
    func.__doc__ = _generate_doc_string_(
        op_proto,
        additional_args_lines=[
S
sneaxiy 已提交
5552
            "act (basestring|None): Activation applied to the output.",
5553 5554 5555 5556 5557 5558
            "name (basestring|None): Name of the output.",
        ],
    )
    func.__doc__ = (
        func.__doc__
        + """
5559 5560 5561

Examples:
  .. code-block:: python
5562

5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592
    import paddle.fluid as fluid
    # example 1: shape(x) = (2, 3, 4, 5), shape(y) = (2, 3, 4, 5)
    x0 = fluid.layers.data(name="x0", shape=[2, 3, 4, 5], dtype='float32')
    y0 = fluid.layers.data(name="y0", shape=[2, 3, 4, 5], dtype='float32')
    z0 = fluid.layers.%s(x0, y0)

    # example 2: shape(X) = (2, 3, 4, 5), shape(Y) = (5)
    x1 = fluid.layers.data(name="x1", shape=[2, 3, 4, 5], dtype='float32')
    y1 = fluid.layers.data(name="y1", shape=[5], dtype='float32')
    z1 = fluid.layers.%s(x1, y1)

    # example 3: shape(X) = (2, 3, 4, 5), shape(Y) = (4, 5), with axis=-1(default) or axis=2
    x2 = fluid.layers.data(name="x2", shape=[2, 3, 4, 5], dtype='float32')
    y2 = fluid.layers.data(name="y2", shape=[4, 5], dtype='float32')
    z2 = fluid.layers.%s(x2, y2, axis=2)

    # example 4: shape(X) = (2, 3, 4, 5), shape(Y) = (3, 4), with axis=1
    x3 = fluid.layers.data(name="x3", shape=[2, 3, 4, 5], dtype='float32')
    y3 = fluid.layers.data(name="y3", shape=[3, 4], dtype='float32')
    z3 = fluid.layers.%s(x3, y3, axis=1)

    # example 5: shape(X) = (2, 3, 4, 5), shape(Y) = (2), with axis=0
    x4 = fluid.layers.data(name="x4", shape=[2, 3, 4, 5], dtype='float32')
    y4 = fluid.layers.data(name="y4", shape=[2], dtype='float32')
    z4 = fluid.layers.%s(x4, y4, axis=0)

    # example 6: shape(X) = (2, 3, 4, 5), shape(Y) = (2, 1), with axis=0
    x5 = fluid.layers.data(name="x5", shape=[2, 3, 4, 5], dtype='float32')
    y5 = fluid.layers.data(name="y5", shape=[2], dtype='float32')
    z5 = fluid.layers.%s(x5, y5, axis=0)
5593 5594 5595 5596 5597 5598 5599 5600 5601 5602
    """
        % (
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
        )
    )
M
minqiyang 已提交
5603 5604


5605
def _logical_op(op_name, x, y, out=None, name=None, binary_op=True):
J
Jiabin Yang 已提交
5606
    if _non_static_mode():
5607
        op = getattr(_legacy_C_ops, op_name)
5608 5609 5610 5611
        if binary_op:
            return op(x, y)
        else:
            return op(x)
5612
    check_variable_and_dtype(
5613 5614
        x,
        "x",
5615
        ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
5616 5617
        op_name,
    )
5618
    if y is not None:
5619
        check_variable_and_dtype(
5620 5621
            y,
            "y",
5622
            ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
5623 5624
            op_name,
        )
5625
    if out is not None:
5626
        check_type(out, "out", Variable, op_name)
5627

M
minqiyang 已提交
5628 5629
    helper = LayerHelper(op_name, **locals())

5630 5631 5632
    if binary_op and x.dtype != y.dtype:
        raise ValueError(
            "(InvalidArgument) The DataType of %s Op's Variable must be consistent, but received %s and %s."
5633 5634
            % (op_name, x.dtype, y.dtype)
        )
M
minqiyang 已提交
5635 5636

    if out is None:
5637
        out = helper.create_variable_for_type_inference(dtype=x.dtype)
M
minqiyang 已提交
5638 5639

    if binary_op:
5640 5641 5642
        helper.append_op(
            type=op_name, inputs={"X": x, "Y": y}, outputs={"Out": out}
        )
M
minqiyang 已提交
5643 5644 5645 5646 5647 5648
    else:
        helper.append_op(type=op_name, inputs={"X": x}, outputs={"Out": out})

    return out


5649 5650 5651
@templatedoc()
def clip(x, min, max, name=None):
    """
5652
        :old_api: paddle.fluid.layers.clip
5653

5654 5655 5656 5657
    ${comment}

    Args:
        x(${x_type}): ${x_comment}
S
SunGaofeng 已提交
5658 5659
        min(float): ${min_comment}
        max(float): ${max_comment}
5660 5661
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
5662
                             For more information, please refer to :ref:`api_guide_Name`
5663 5664

    Returns:
S
SunGaofeng 已提交
5665 5666 5667 5668
        ${out_comment}

    Return Type:
        ${out_type}
5669 5670 5671 5672

    Examples:
        .. code-block:: python

S
SunGaofeng 已提交
5673
            import paddle.fluid as fluid
S
SunGaofeng 已提交
5674
            input = fluid.data(
5675 5676
                name='data', shape=[1], dtype='float32')
            reward = fluid.layers.clip(x=input, min=-1.0, max=1.0)
5677 5678 5679
    """

    helper = LayerHelper("clip", **locals())
5680
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'clip')
5681 5682

    if name is None:
5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696
        name = unique_name.generate_with_ignorable_key(
            ".".join([helper.name, 'tmp'])
        )

    out = helper.create_variable(
        type=x.type, name=name, dtype=x.dtype, persistable=False
    )

    helper.append_op(
        type="clip",
        inputs={"X": x},
        attrs={"min": min, "max": max},
        outputs={"Out": out},
    )
5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708

    return out


@templatedoc()
def clip_by_norm(x, max_norm, name=None):
    """
    ${comment}

    Args:
        x(${x_type}): ${x_comment}
        max_norm(${max_norm_type}): ${max_norm_comment}
5709 5710 5711
        name(str, optional): For detailed information, please refer
            to :ref:`api_guide_Name`. Usually name is no need to set and
            None by default.
5712 5713

    Returns:
5714
        Tensor:
W
wangguanzhong 已提交
5715

5716
        out(${out_type}): ${out_comment}
5717

W
wangguanzhong 已提交
5718

5719 5720 5721
    Examples:
        .. code-block:: python

5722
            import paddle
5723
            import paddle.fluid as fluid
5724

5725 5726 5727
            input = paddle.to_tensor([[2.0, 2.0], [2.0, 2.0]], dtype='float32')
            reward = fluid.layers.clip_by_norm(x=input, max_norm=1.0)
            # [[0.5, 0.5], [0.5, 0.5]]
5728 5729
    """

L
lyq 已提交
5730
    if in_dygraph_mode():
5731
        return _C_ops.clip_by_norm(x, max_norm)
J
Jiabin Yang 已提交
5732
    if _non_static_mode():
5733
        return _legacy_C_ops.clip_by_norm(x, 'max_norm', max_norm)
5734

5735
    helper = LayerHelper("clip_by_norm", **locals())
5736
    check_variable_and_dtype(x, 'X', ['float32', 'float16'], 'clip_by_norm')
5737
    check_type(max_norm, 'max_norm', (float), 'clip_by_norm')
5738 5739

    if name is None:
5740 5741 5742
        name = unique_name.generate_with_ignorable_key(
            ".".join([helper.name, 'tmp'])
        )
S
sneaxiy 已提交
5743

5744 5745 5746
    out = helper.create_variable(
        type=x.type, name=name, dtype=x.dtype, persistable=False
    )
5747

5748 5749 5750 5751 5752 5753
    helper.append_op(
        type="clip_by_norm",
        inputs={"X": x},
        attrs={"max_norm": max_norm},
        outputs={"Out": out},
    )
5754 5755

    return out
X
Xin Pan 已提交
5756 5757


5758
@deprecated(since="2.0.0", update_to="paddle.mean")
X
Xin Pan 已提交
5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769
@templatedoc()
def mean(x, name=None):
    """
    ${comment}

    Args:
        x(${x_type}): ${x_comment}
        name(basestring|None): Name of the output.

    Returns:
        out(${out_type}): ${out_comment}
5770 5771 5772 5773

    Examples:
        .. code-block:: python

5774
            import paddle
5775
            import paddle.fluid as fluid
5776 5777
            paddle.enable_static()

5778 5779
            input = fluid.layers.data(
                name='data', shape=[2, 3], dtype='float32')
5780
            mean = paddle.mean(input)
X
Xin Pan 已提交
5781
    """
5782

5783
    if _in_legacy_dygraph():
5784
        return _legacy_C_ops.mean(x)
5785
    if in_dygraph_mode():
5786
        return _C_ops.mean_all(x)
X
Xin Pan 已提交
5787 5788

    helper = LayerHelper("mean", **locals())
5789
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'mean')
5790
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
X
Xin Pan 已提交
5791

5792 5793 5794
    helper.append_op(
        type="mean", inputs={"X": x}, attrs={}, outputs={"Out": out}
    )
X
Xin Pan 已提交
5795 5796 5797 5798

    return out


C
chengduo 已提交
5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809
@templatedoc()
def merge_selected_rows(x, name=None):
    """
    ${comment}

    Args:
        x(${x_type}): ${x_comment}
        name(basestring|None): Name of the output.

    Returns:
        out(${out_type}): ${out_comment}
5810 5811 5812 5813

    Examples:
        .. code-block:: python

5814
            import paddle.fluid as fluid
5815 5816 5817 5818 5819
            b = fluid.default_main_program().global_block()
            var = b.create_var(
                name="X", dtype="float32", persistable=True,
                type=fluid.core.VarDesc.VarType.SELECTED_ROWS)
            y = fluid.layers.merge_selected_rows(var)
C
chengduo 已提交
5820
    """
5821 5822 5823
    if in_dygraph_mode():
        return _C_ops.merge_selected_rows(x)

5824
    if _non_static_mode():
5825
        return _legacy_C_ops.merge_selected_rows(x)
C
chengduo 已提交
5826 5827 5828

    helper = LayerHelper("merge_selected_rows", **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
5829 5830 5831 5832 5833 5834
    helper.append_op(
        type="merge_selected_rows",
        inputs={"X": x},
        attrs={},
        outputs={"Out": out},
    )
C
chengduo 已提交
5835 5836 5837
    return out


X
Xin Pan 已提交
5838 5839
def mul(x, y, x_num_col_dims=1, y_num_col_dims=1, name=None):
    """
L
liu zhengxi 已提交
5840 5841 5842 5843 5844 5845 5846 5847
    Mul Operator.
    This operator is used to perform matrix multiplication for input $x$ and $y$.
    The equation is:

    ..  math::
        Out = x * y

    Both the input $x$ and $y$ can carry the LoD (Level of Details) information, or not. But the output only shares the LoD information with input $x$.
X
Xin Pan 已提交
5848 5849

    Args:
L
liu zhengxi 已提交
5850 5851
        x (Variable): The first input Tensor/LoDTensor of mul_op.
        y (Variable): The second input Tensor/LoDTensor of mul_op.
5852 5853 5854
        x_num_col_dims (int, optional): The mul_op can take tensors with more than two dimensions as its inputs. If the input $x$ is a tensor with more than two dimensions, $x$ will be flattened into a two-dimensional matrix first. The flattening rule is: the first `num_col_dims` will be flattened to form the first dimension of the final matrix (the height of the matrix), and the rest `rank(x) - num_col_dims` dimensions are flattened to form the second dimension of the final matrix (the width of the matrix). As a result, height of the flattened matrix is equal to the product of $x$'s first `x_num_col_dims` dimensions' sizes, and width of the flattened matrix is equal to the product of $x$'s last `rank(x) - num_col_dims` dimensions' size. For example, suppose $x$ is a 6-dimensional tensor with the shape [2, 3, 4, 5, 6], and `x_num_col_dims` = 3. Thus, the flattened matrix will have a shape [2 x 3 x 4, 5 x 6] = [24, 30]. Default is 1.
        y_num_col_dims (int, optional): The mul_op can take tensors with more than two dimensions as its inputs. If the input $y$ is a tensor with more than two dimensions, $y$ will be flattened into a two-dimensional matrix first. The attribute `y_num_col_dims` determines how $y$ is flattened. See comments of `x_num_col_dims` for more details. Default is 1.
        name (str, optional): Name of the output. Normally there is no need for user to set this property. For more information, please refer to :ref:`api_guide_Name`. Default is None.
X
Xin Pan 已提交
5855 5856

    Returns:
L
liu zhengxi 已提交
5857
        Variable(Tensor/LoDTensor): The output Tensor/LoDTensor of mul op.
5858 5859

    Examples:
L
liu zhengxi 已提交
5860
        ..  code-block:: python
5861

5862
            import paddle.fluid as fluid
5863 5864
            import paddle
            paddle.enable_static()
5865 5866 5867 5868 5869
            dataX = fluid.layers.data(name="dataX", append_batch_size = False, shape=[2, 5], dtype="float32")
            dataY = fluid.layers.data(name="dataY", append_batch_size = False, shape=[5, 3], dtype="float32")
            output = fluid.layers.mul(dataX, dataY,
                                      x_num_col_dims = 1,
                                      y_num_col_dims = 1)
5870

5871

X
Xin Pan 已提交
5872
    """
J
Jiabin Yang 已提交
5873
    if _non_static_mode():
5874 5875 5876 5877 5878 5879 5880 5881
        return _legacy_C_ops.mul(
            x,
            y,
            'x_num_col_dims',
            x_num_col_dims,
            'y_num_col_dims',
            y_num_col_dims,
        )
X
Xin Pan 已提交
5882

5883 5884
    inputs = {"X": [x], "Y": [y]}
    attrs = {"x_num_col_dims": x_num_col_dims, "y_num_col_dims": y_num_col_dims}
X
Xin Pan 已提交
5885
    helper = LayerHelper("mul", **locals())
5886 5887
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'mul')
    check_variable_and_dtype(y, 'y', ['float16', 'float32', 'float64'], 'mul')
5888
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
X
Xin Pan 已提交
5889

5890 5891 5892
    helper.append_op(
        type="mul", inputs={"X": x, "Y": y}, attrs=attrs, outputs={"Out": out}
    )
X
Xin Pan 已提交
5893 5894 5895
    return out


M
minqiyang 已提交
5896 5897
def hash(input, hash_size, num_hash=1, name=None):
    """
5898

Z
zhupengyang 已提交
5899
    This OP hash the input to an integer less than the hash_size.
M
minqiyang 已提交
5900 5901
    The hash algorithm we used was xxHash - Extremely fast hash algorithm
    (https://github.com/Cyan4973/xxHash/tree/v0.6.5)
M
minqiyang 已提交
5902 5903

    Args:
Z
zhupengyang 已提交
5904 5905 5906 5907 5908 5909
        input(Variable): A **Two-Dimensional** LoDTensor with type int32, int64.
             **Only support LoDTensor**.
        num_hash(int, optional): The times of hash, default is 1.
        name(str, optional): The default value is None. Normally there is no
            need for user to set this property. For more information, please
            refer to :ref:`api_guide_Name`.
M
minqiyang 已提交
5910 5911

    Returns:
Z
zhupengyang 已提交
5912
       Variable: A LoDTensor with the same data type as input.
M
minqiyang 已提交
5913 5914

    Examples:
Z
zhupengyang 已提交
5915
        .. code-block:: python
H
haowang101779990 已提交
5916

5917
            import paddle.fluid as fluid
Z
zhupengyang 已提交
5918
            import numpy as np
5919 5920
            import paddle
            paddle.enable_static()
5921

Z
zhupengyang 已提交
5922
            place = fluid.core.CPUPlace()
5923

5924 5925
            x = fluid.data(name="x", shape=[2,2], dtype="int32", lod_level=1)
            res = fluid.layers.hash(name="res", input=x, hash_size=1000, num_hash=4)
5926

Z
zhupengyang 已提交
5927 5928 5929 5930
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
            in1 = np.array([[1,2],[3,4]]).astype("int32")
            print(in1)
5931
            x_i = fluid.create_lod_tensor(in1, [[0, 2]], place)
Z
zhupengyang 已提交
5932 5933 5934 5935 5936 5937 5938 5939 5940 5941
            res = exe.run(fluid.default_main_program(), feed={'x':x_i}, fetch_list=[res], return_numpy=False)
            print(np.array(res[0]))
            # [[[722]
            #   [407]
            #   [337]
            #   [395]]
            #  [[603]
            #   [590]
            #   [386]
            #   [901]]]
M
minqiyang 已提交
5942
    """
5943
    check_variable_and_dtype(input, 'input', ['int32', 'int64'], 'hash')
5944 5945
    check_type(hash_size, 'hash_size', int, 'hash')
    check_type(num_hash, 'num_hash', int, 'hash')
M
minqiyang 已提交
5946
    helper = LayerHelper('hash', **locals())
5947 5948 5949 5950 5951 5952 5953 5954 5955
    out = helper.create_variable_for_type_inference(
        helper.input_dtype(), stop_gradient=True
    )
    helper.append_op(
        type='hash',
        inputs={'X': input},
        outputs={'Out': out},
        attrs={'num_hash': num_hash, 'mod_by': hash_size},
    )
M
minqiyang 已提交
5956
    return out
G
gmcather 已提交
5957 5958


D
dengkaipeng 已提交
5959
@templatedoc()
5960 5961
def grid_sampler(x, grid, name=None):
    """
5962

5963
    This operation samples input X by using bilinear interpolation based on
T
tianshuo78520a 已提交
5964
    flow field grid, which is usually generated by :code:`affine_grid` . The grid of
K
Kaipeng Deng 已提交
5965 5966
    shape [N, H, W, 2] is the concatenation of (x, y) coordinates
    with shape [N, H, W] each, where x is indexing the 4th dimension
T
tianshuo78520a 已提交
5967 5968
    (in width dimension) of input data x and y is indexing the 3rd
    dimension (in height dimension), finally results is the bilinear
5969
    interpolation value of 4 nearest corner points. The output tensor
K
Kaipeng Deng 已提交
5970
    shape will be [N, C, H, W].
5971

H
haowang101779990 已提交
5972
    .. code-block:: text
5973

H
haowang101779990 已提交
5974 5975
        Step 1:
        Get (x, y) grid coordinates and scale to [0, H-1/W-1].
5976

K
Kaipeng Deng 已提交
5977 5978 5979 5980
        .. code-block:: text

            grid_x = 0.5 * (grid[:, :, :, 0] + 1) * (W - 1)
            grid_y = 0.5 * (grid[:, :, :, 1] + 1) * (H - 1)
5981

H
haowang101779990 已提交
5982 5983 5984
        Step 2:
        Indices input data X with grid (x, y) in each [H, W] area, and bilinear
        interpolate point value by 4 nearest points.
5985

H
haowang101779990 已提交
5986 5987 5988 5989 5990 5991 5992 5993 5994
          wn ------- y_n ------- en
          |           |           |
          |          d_n          |
          |           |           |
         x_w --d_w-- grid--d_e-- x_e
          |           |           |
          |          d_s          |
          |           |           |
          ws ------- y_s ------- wn
5995

H
haowang101779990 已提交
5996 5997 5998 5999
        x_w = floor(x)              // west side x coord
        x_e = x_w + 1               // east side x coord
        y_n = floor(y)              // north side y coord
        y_s = y_s + 1               // south side y coord
6000

H
haowang101779990 已提交
6001 6002 6003 6004
        d_w = grid_x - x_w          // distance to west side
        d_e = x_e - grid_x          // distance to east side
        d_n = grid_y - y_n          // distance to north side
        d_s = y_s - grid_y          // distance to south side
6005

H
haowang101779990 已提交
6006 6007 6008 6009
        wn = X[:, :, y_n, x_w]      // north-west point value
        en = X[:, :, y_n, x_e]      // north-east point value
        ws = X[:, :, y_s, x_w]      // south-east point value
        es = X[:, :, y_s, x_w]      // north-east point value
6010

H
haowang101779990 已提交
6011 6012
        output = wn * d_e * d_s + en * d_w * d_s
               + ws * d_e * d_n + es * d_w * d_n
D
dengkaipeng 已提交
6013 6014

    Args:
K
Kaipeng Deng 已提交
6015 6016 6017 6018 6019 6020 6021 6022 6023
        x(Variable): The input tensor, which is a 4-D tensor with shape
                     [N, C, H, W], N is the batch size, C is the channel
                     number, H and W is the feature height and width.
                     The data type is float32 or float64.
        grid(Variable): Input grid tensor of shape [N, H, W, 2]. The
                        data type is float32 or float64.
        name(str, optional): For detailed information, please refer
                             to :ref:`api_guide_Name`. Usually name is no need to set and
                             None by default.
D
dengkaipeng 已提交
6024 6025

    Returns:
H
haowang101779990 已提交
6026
        Variable: Output of shape [N, C, H, W] data samples input X
K
Kaipeng Deng 已提交
6027 6028
                  using bilnear interpolation based on input grid.
                  The data type is same as input tensor.
6029

H
haowang101779990 已提交
6030 6031 6032 6033
    Examples:

        .. code-block:: python

K
Kaipeng Deng 已提交
6034
            import paddle.fluid as fluid
6035 6036
            import paddle.fluid as fluid
            import paddle
K
Kaipeng Deng 已提交
6037

6038
            paddle.enable_static()
K
Kaipeng Deng 已提交
6039 6040
            # use with affine_grid
            x = fluid.data(name='x', shape=[None, 10, 32, 32], dtype='float32')
K
Kaipeng Deng 已提交
6041 6042
            theta = fluid.layers.data(name='theta', shape=[2, 3], dtype='float32')
            grid = fluid.layers.affine_grid(theta=theta, out_shape=[3, 10, 32, 32])
H
haowang101779990 已提交
6043
            out = fluid.layers.grid_sampler(x=x, grid=grid)
6044

D
dengkaipeng 已提交
6045 6046 6047
    """
    helper = LayerHelper("grid_sampler", **locals())

6048
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'grid_sampler')
6049 6050 6051
    check_variable_and_dtype(
        grid, 'grid', ['float32', 'float64'], 'grid_sampler'
    )
D
dengkaipeng 已提交
6052 6053 6054 6055 6056 6057
    if not isinstance(x, Variable):
        return ValueError("The x should be a Variable")

    if not isinstance(grid, Variable):
        return ValueError("The grid should be a Variable")

6058
    out = helper.create_variable_for_type_inference(x.dtype)
D
dengkaipeng 已提交
6059 6060
    ipts = {'X': x, 'Grid': grid}

6061 6062
    attrs = {'use_cudnn': False} if core.is_compiled_with_rocm() else {}

6063 6064 6065
    helper.append_op(
        type='grid_sampler', inputs=ipts, outputs={'Output': out}, attrs=attrs
    )
6066 6067 6068
    return out


G
gmcather 已提交
6069
def log_loss(input, label, epsilon=1e-4, name=None):
6070
    r"""
6071

G
gmcather 已提交
6072 6073 6074 6075 6076 6077 6078
    **Negative Log Loss Layer**

    This layer accepts input predictions and target label and returns the
    negative log loss.

    .. math::

6079 6080
        Out = -label * \log{(input + \epsilon)}
              - (1 - label) * \log{(1 - input + \epsilon)}
G
gmcather 已提交
6081 6082

    Args:
6083
        input (Tensor|list):  A 2-D tensor with shape [N x 1], where N is the
G
gmcather 已提交
6084
                                batch size. This input is a probability computed
Y
Yibing Liu 已提交
6085
                                by the previous operator. Data type float32.
6086
        label (Tensor|list):  The ground truth which is a 2-D tensor with
6087
                                shape [N x 1], where N is the batch size.
Y
Yibing Liu 已提交
6088 6089
                                Data type float32.
        epsilon (float, optional): A small number for numerical stability. Default 1e-4.
6090
        name(str|None): For detailed information, please refer to
Y
Yibing Liu 已提交
6091
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
G
gmcather 已提交
6092 6093

    Returns:
6094
        Tensor, which shape is [N x 1], data type is float32.
G
gmcather 已提交
6095 6096 6097 6098

    Examples:
        .. code-block:: python

6099 6100 6101 6102 6103 6104
          import paddle
          import paddle.nn.functional as F

          label = paddle.randn((10,1))
          prob = paddle.randn((10,1))
          cost = F.log_loss(input=prob, label=label)
G
gmcather 已提交
6105
    """
6106
    return paddle.nn.functional.log_loss(input, label, epsilon, name)
G
gmcather 已提交
6107 6108


6109 6110 6111
def bilinear_tensor_product(
    x, y, size, act=None, name=None, param_attr=None, bias_attr=None
):
6112
    r"""
6113 6114
    :api_attr: Static Graph

Y
Yibing Liu 已提交
6115
    **Bilinear Tensor Product Layer**
Q
Qiao Longfei 已提交
6116

Q
Qiao Longfei 已提交
6117
    This layer performs bilinear tensor product on two inputs.
Q
Qiao Longfei 已提交
6118 6119 6120
    For example:

    .. math::
H
haowang101779990 已提交
6121
       out_{i} = x * W_{i} * {y^\mathrm{T}}, i=0,1,...,size-1
Q
Qiao Longfei 已提交
6122

Q
Qiao Longfei 已提交
6123
    In this formula:
6124 6125
      - :math:`x`: the first input contains M elements, shape is [batch_size, M].
      - :math:`y`: the second input contains N elements, shape is [batch_size, N].
Y
Yibing Liu 已提交
6126
      - :math:`W_{i}`: the i-th learned weight, shape is [M, N].
H
haowang101779990 已提交
6127
      - :math:`out_{i}`: the i-th element of out, shape is [batch_size, size].
Q
Qiao Longfei 已提交
6128 6129 6130
      - :math:`y^\mathrm{T}`: the transpose of :math:`y_{2}`.

    Args:
6131
        x (Variable): 2-D input tensor with shape [batch_size, M]. Data type
Y
Yibing Liu 已提交
6132
            is float32 or float64.
6133
        y (Variable): 2-D input tensor with shape [batch_size, N]. Data type
Y
Yibing Liu 已提交
6134
            should be same as **x**.
Q
Qiao Longfei 已提交
6135
        size (int): The dimension of this layer.
Y
Yibing Liu 已提交
6136
        act (str|None): Activation to be applied to the output of this layer. Default None.
6137
        name(str|None): For detailed information, please refer to
Y
Yibing Liu 已提交
6138
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
6139 6140
        param_attr (ParamAttr|None): To specify the weight parameter attribute.
            Default: None, which means the default weight parameter property is
Y
Yibing Liu 已提交
6141
            used. See usage for details in :ref:`api_fluid_ParamAttr` .
6142 6143
        bias_attr (ParamAttr|None): To specify the bias parameter attribute.
            Default: None, which means the default bias parameter property is
Y
Yibing Liu 已提交
6144
            used. See usage for details in :ref:`api_fluid_ParamAttr` .
Q
Qiao Longfei 已提交
6145
    Returns:
Y
Yibing Liu 已提交
6146
        Variable: A 2-D Tensor of shape [batch_size, size]. Data type is the same as input **x**.
Q
Qiao Longfei 已提交
6147 6148 6149 6150

    Examples:
        .. code-block:: python

6151 6152 6153 6154 6155
            import paddle
            paddle.enable_static()
            layer1 = paddle.static.data("t1", shape=[-1, 5], dtype="float32")
            layer2 = paddle.static.data("t2", shape=[-1, 4], dtype="float32")
            tensor = paddle.static.nn.bilinear_tensor_product(x=layer1, y=layer2, size=1000)
Q
Qiao Longfei 已提交
6156 6157
    """
    helper = LayerHelper('bilinear_tensor_product', **locals())
Q
Qiao Longfei 已提交
6158
    dtype = helper.input_dtype('x')
Q
Qiao Longfei 已提交
6159 6160 6161

    param_shape = [size, x.shape[1], y.shape[1]]

6162 6163 6164
    w = helper.create_parameter(
        attr=helper.param_attr, shape=param_shape, dtype=dtype, is_bias=False
    )
6165
    out = helper.create_variable_for_type_inference(dtype=dtype)
Q
Qiao Longfei 已提交
6166 6167 6168 6169

    inputs = {"X": x, "Y": y, "Weight": w}
    if helper.bias_attr:
        bias_size = [1, size]
6170 6171 6172
        bias = helper.create_parameter(
            attr=helper.bias_attr, shape=bias_size, dtype=dtype, is_bias=True
        )
Q
Qiao Longfei 已提交
6173
        inputs["Bias"] = bias
6174 6175 6176
    helper.append_op(
        type="bilinear_tensor_product", inputs=inputs, outputs={"Out": out}
    )
Q
Qiao Longfei 已提交
6177 6178 6179

    # add activation
    return helper.append_activation(out)
C
chengduo 已提交
6180 6181 6182 6183 6184


@templatedoc()
def get_tensor_from_selected_rows(x, name=None):
    """
6185 6186 6187 6188 6189 6190 6191 6192 6193
    This operator gets tensor data from input with SelectedRows type, and outputs a LoDTensor.

    .. code-block:: text

        input x is SelectedRows:
           x.rows = [0, 5, 5, 4, 19]
           x.height = 20
           x.value = [[1, 1] [2, 2] [2, 2] [3, 3] [6, 6]]

6194
        Output is LoDTensor:
6195 6196 6197 6198 6199 6200
           out.shape = [5, 2]
           out.data = [[1, 1],
                       [2, 2],
                       [2, 2],
                       [3, 3],
                       [6, 6]]
C
chengduo 已提交
6201 6202

    Args:
6203 6204 6205
        x(SelectedRows): Input with SelectedRows type. The data type is float32, float64, int32 or int64.
        name(str, optional): The default value is None.  Normally there is no need for user to set this property.
            For more information, please refer to :ref:`api_guide_Name` .
C
chengduo 已提交
6206 6207

    Returns:
6208
        Variable: LoDTensor transformed from SelectedRows. The data type is same with input.
B
bdzhuxiaoning 已提交
6209 6210 6211

    Examples:
        .. code-block:: python
6212

B
bdzhuxiaoning 已提交
6213 6214 6215 6216
            import paddle.fluid as fluid
            b = fluid.default_main_program().global_block()
            input = b.create_var(name="X", dtype="float32", persistable=True, type=fluid.core.VarDesc.VarType.SELECTED_ROWS)
            out = fluid.layers.get_tensor_from_selected_rows(input)
C
chengduo 已提交
6217 6218
    """

6219 6220 6221 6222 6223
    check_type(x, 'x', Variable, 'get_tensor_from_selected_rows')
    if x.type != core.VarDesc.VarType.SELECTED_ROWS:
        raise TypeError(
            "The type of 'x' in get_tensor_from_selected_rows must be SELECTED_ROWS."
        )
C
chengduo 已提交
6224 6225
    helper = LayerHelper('get_tensor_from_selected_rows', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
6226 6227 6228 6229 6230 6231
    helper.append_op(
        type='get_tensor_from_selected_rows',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={},
    )
C
chengduo 已提交
6232
    return out
6233 6234


H
heqiaozhi 已提交
6235
def continuous_value_model(input, cvm, use_cvm=True):
6236
    r"""
H
fix doc  
heqiaozhi 已提交
6237

H
heqiaozhi 已提交
6238
    **continuous_value_model layers**
H
fix doc  
heqiaozhi 已提交
6239

Z
zhoushiyu 已提交
6240
    Now, this OP is used in CTR project to remove or dispose show and click value in :attr:`input`.
H
fix doc  
heqiaozhi 已提交
6241

Z
zhoushiyu 已提交
6242 6243
    :attr:`input` is an embedding vector including show and click value, whose shape is :math:`[N, D]` (N is batch size. D is `2 + embedding dim` ).
    Show and click at first two dims of embedding vector D.
T
tianshuo78520a 已提交
6244
    If :attr:`use_cvm` is True, it will calculate :math:`log(show)` and :math:`log(click)` , and output shape is :math:`[N, D]` .
Z
zhoushiyu 已提交
6245 6246
    If :attr:`use_cvm` is False, it will remove show and click from :attr:`input` , and output shape is :math:`[N, D - 2]` .
    :attr:`cvm` is show_click info, whose shape is :math:`[N, 2]` .
H
fix doc  
heqiaozhi 已提交
6247

Z
zhoushiyu 已提交
6248 6249 6250 6251 6252 6253 6254
    Args:
        input (Variable): The input variable. A 2-D LoDTensor with shape :math:`[N, D]` , where N is the batch size, D is `2 + the embedding dim` . `lod level = 1` .
        A Tensor with type float32, float64.
        cvm (Variable): Show and click variable. A 2-D Tensor with shape :math:`[N, 2]` , where N is the batch size, 2 is show and click.
        A Tensor with type float32, float64.
        use_cvm  (bool):  Use show_click or not. if use, the output dim is the same as input.
                          if not use, the output dim is `input dim - 2` (remove show and click)
H
fix doc  
heqiaozhi 已提交
6255

H
heqiaozhi 已提交
6256
    Returns:
H
fix doc  
heqiaozhi 已提交
6257

Z
zhoushiyu 已提交
6258 6259
        Variable: A 2-D LodTensor with shape :math:`[N, M]` . if :attr:`use_cvm` = True, M is equal to input dim D. if False, M is equal to `D - 2`. \
        A Tensor with same type as input.
H
fix doc  
heqiaozhi 已提交
6260

H
heqiaozhi 已提交
6261
    Examples:
H
fix doc  
heqiaozhi 已提交
6262

H
heqiaozhi 已提交
6263
        .. code-block:: python
H
fix doc  
heqiaozhi 已提交
6264

6265
          import paddle.fluid as fluid
Z
zhoushiyu 已提交
6266 6267
          input = fluid.data(name="input", shape=[64, 1], dtype="int64")
          label = fluid.data(name="label", shape=[64, 1], dtype="int64")
H
heqiaozhi 已提交
6268 6269 6270 6271 6272 6273 6274 6275
          embed = fluid.layers.embedding(
                            input=input,
                            size=[100, 11],
                            dtype='float32')
          ones = fluid.layers.fill_constant_batch_size_like(input=label, shape=[-1, 1], dtype="int64", value=1)
          show_clk = fluid.layers.cast(fluid.layers.concat([ones, label], axis=1), dtype='float32')
          show_clk.stop_gradient = True
          input_with_cvm = fluid.layers.continuous_value_model(embed, show_clk, True)
H
fix doc  
heqiaozhi 已提交
6276

H
heqiaozhi 已提交
6277 6278 6279
    """
    helper = LayerHelper('cvm', **locals())
    out = helper.create_variable(dtype=input.dtype)
6280 6281 6282 6283 6284 6285 6286 6287 6288
    check_variable_and_dtype(
        input, 'input', ['float16', 'float32', 'float64'], 'cvm'
    )
    helper.append_op(
        type='cvm',
        inputs={'X': [input], 'CVM': [cvm]},
        outputs={'Y': [out]},
        attrs={"use_cvm": use_cvm},
    )
H
heqiaozhi 已提交
6289
    return out
Z
zhoukunsheng 已提交
6290 6291


6292
def unfold(x, kernel_sizes, strides=1, paddings=0, dilations=1, name=None):
6293
    r"""
6294

S
SunGaofeng 已提交
6295
    This op returns a col buffer of sliding local blocks of input x, also known
6296
    as im2col for batched 2D image tensors. For each block under the convolution filter,
T
tianshuo78520a 已提交
6297
    all element will be rearranged as a column. While the convolution filter sliding over
6298 6299
    the input feature map, a series of such columns will be formed.

S
SunGaofeng 已提交
6300
    For each input :math:`x` with shape [N, C, H, W], the output shape [N, Cout, Lout]
6301 6302 6303 6304
    can be calculated as following.

    .. math::

6305
        dkernel[0] &= dilations[0] \times (kernel\_sizes[0] - 1) + 1
6306

6307
        dkernel[1] &= dilations[1] \times (kernel\_sizes[1] - 1) + 1
6308

6309
        hout &= \frac{H + paddings[0] + paddings[2] - dkernel[0]}{strides[0]} + 1
6310

6311
        wout &= \frac{W + paddings[1] + paddings[3] - dkernel[1]}{strides[1]} + 1
6312

6313
        Cout &= C \times kernel\_sizes[0] \times kernel\_sizes[1]
6314

6315
        Lout &= hout \times wout
6316 6317


S
SunGaofeng 已提交
6318
    Parameters:
6319
        x(Tensor):              4-D Tensor, input tensor of format [N, C, H, W],
S
SunGaofeng 已提交
6320
                                  data type can be float32 or float64
6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332
        kernel_sizes(int|list):   The size of convolution kernel, should be [k_h, k_w]
                                  or an integer k treated as [k, k].
        strides(int|list):        The strides, should be [stride_h, stride_w]
                                  or an integer stride treated as [sride, stride].
                                  For default, strides will be [1, 1].
        paddings(int|list):       The paddings of each dimension, should be
                                  [padding_top, padding_left, padding_bottom, padding_right]
                                  or [padding_h, padding_w] or an integer padding.
                                  If [padding_h, padding_w] was given, it will expanded to
                                  [padding_h, padding_w, padding_h, padding_w]. If an integer
                                  padding was given, [padding, padding, padding, padding] will
                                  be used. For default, paddings will be [0, 0, 0, 0]
T
tianshuo78520a 已提交
6333
        dilations(int|list):      the dilations of convolution kernel, should be
T
tianshuo78520a 已提交
6334
                                  [dilation_h, dilation_w], or an integer dilation treated as
6335
                                  [dilation, dilation]. For default, it will be [1, 1].
6336 6337
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
6338
                             For more information, please refer to :ref:`api_guide_Name`
6339

6340

6341
    Returns:
6342
        The tensor corresponding to the sliding local blocks.
6343 6344 6345
        The output shape is [N, Cout, Lout] as decriabled above.
        Cout is the  total number of values within each block,
        and Lout is the total number of such blocks.
S
SunGaofeng 已提交
6346 6347 6348
        The data type of output is the same as the input :math:`x`

    Return Type:
6349
        Tensor
6350 6351 6352 6353 6354

    Examples:

        .. code-block:: python

6355 6356 6357 6358 6359
            import paddle
            import paddle.nn.functional as F

            x = paddle.randn((100,3,224,224))
            y = F.unfold(x, [3, 3], 1, 1, 1)
6360 6361
    """

6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381
    return paddle.nn.functional.unfold(
        x, kernel_sizes, strides, paddings, dilations, name
    )


def deformable_roi_pooling(
    input,
    rois,
    trans,
    no_trans=False,
    spatial_scale=1.0,
    group_size=[1, 1],
    pooled_height=1,
    pooled_width=1,
    part_size=None,
    sample_per_part=1,
    trans_std=0.1,
    position_sensitive=False,
    name=None,
):
6382
    r"""
6383

6384
    Deformable ROI Pooling Layer
6385

6386
    Performs deformable region-of-interest pooling on inputs. As described
6387
    in `Deformable Convolutional Networks <https://arxiv.org/abs/1703.06211>`_, it will get offset for each bin after
6388
    roi pooling so that pooling at correct region. Batch_size will change to the number of region bounding boxes after deformable_roi_pooling.
6389

6390
    The operation has three steps:
6391

6392
    1. Dividing each region proposal into equal-sized sections with the pooled_width and pooled_height.
6393

6394 6395
    2. Add offset to pixel in ROI to get new location and the new value which are computed directly through
       bilinear interpolation with four nearest pixel.
6396

6397
    3. Sample several points in each bin to get average values as output.
6398 6399


6400 6401 6402 6403 6404 6405 6406 6407 6408
    Args:
        input (Variable):The input of deformable roi pooling and it is tensor which value type is float32. The shape of input is
                         [N, C, H, W]. Where N is batch size, C is number of input channels,
                         H is height of the feature, and W is the width of the feature.
        rois (Variable): ROIs (Regions of Interest) with type float32 to pool over. It should be
                         a 2-D LoDTensor of shape (num_rois, 4), and the lod level
                         is 1. Given as [[x1, y1, x2, y2], ...], (x1, y1) is
                         the top left coordinates, and (x2, y2) is the bottom
                         right coordinates, which value type is float32.
6409 6410 6411
        trans (Variable): Offset of features on ROIs while pooling which value type is float32. The format is [N, C, H, W], where
                          N is number of ROIs, C is number of channels, which indicate the offset distance
                          in the x and y directions, H is pooled height, and W is pooled width.
6412 6413 6414 6415
        no_trans (bool): Whether to add offset to get new value or not while roi pooling, which value with type bool is True or False.
                         If value is True, no offset will be added in operation. Default: False.
        spatial_scale (float): Ratio of input feature map height (or width) to raw image height (or width), which value type is float32.
                         Equals the reciprocal of total stride in convolutional layers, Default: 1.0.
6416
        group_size (list|tuple): The number of groups which input channels are divided and the input is list or tuple, which value type is int32. (eg.number of input channels
6417
                          is k1 * k2 * (C + 1), which k1 and k2 are group width and height and C+1 is number of output
T
tianshuo78520a 已提交
6418
                          channels.) eg.(4, 6), which 4 is height of group and 6 is width of group. Default: [1, 1].
6419 6420 6421 6422 6423 6424 6425
        pooled_height (int): The pooled output height which value type is int32. Default: 1.
        pooled_width (int): The pooled output width which value type is int32. Default: 1.
        part_size (list|tuple): The height and width of offset which values in list or tuple is int32, eg.(4, 6), which height is 4 and width is 6, and values always equal to pooled_height \
                         and pooled_width. Default: if None, default value is [pooled_height, pooled_width].
        sample_per_part (int): The number of samples in each bin which value type is int32. If value is bigger, it will consume more performance. Default: 1.
        trans_std (float): Coefficient of offset which value type is float32. It controls weight of offset. Default: 0.1.
        position_sensitive (bool): Whether to choose deformable psroi pooling mode or not, and value type is bool(True or False). If value is False, input dimension equals to output dimension. \
T
tianshuo78520a 已提交
6426
                                   If value is True, input dimension should be output dimension * pooled_height * pooled_width. Default: False.
6427 6428 6429 6430
        name (str|None): Name of layer. Default: None.
    Returns:
        Variable: Output of deformable roi pooling is that, if position sensitive is False, input dimension equals to output dimension. If position sensitive is True,\
                  input dimension should be the result of output dimension divided by pooled height and pooled width.
C
cjt222 已提交
6431 6432 6433 6434

    Examples:
      .. code-block:: python

6435 6436
        # position_sensitive=True
        import paddle.fluid as fluid
C
chengjuntao 已提交
6437
        input = fluid.data(name="input",
6438 6439
                           shape=[2, 192, 64, 64],
                           dtype='float32')
C
chengjuntao 已提交
6440 6441
        rois = fluid.data(name="rois",
                          shape=[-1, 4],
6442
                          dtype='float32',
C
chengjuntao 已提交
6443 6444
                          lod_level=1)
        trans = fluid.data(name="trans",
6445 6446 6447 6448 6449
                           shape=[2, 384, 64, 64],
                           dtype='float32')
        x = fluid.layers.deformable_roi_pooling(input=input,
                                                rois=rois,
                                                trans=trans,
C
chengjuntao 已提交
6450
                                                no_trans=False,
6451
                                                spatial_scale=1.0,
C
chengjuntao 已提交
6452 6453 6454 6455
                                                group_size=(1, 1),
                                                pooled_height=8,
                                                pooled_width=8,
                                                part_size=(8, 8),
6456
                                                sample_per_part=4,
C
chengjuntao 已提交
6457 6458
                                                trans_std=0.1,
                                                position_sensitive=True)
6459

6460
        # position_sensitive=False
6461
        import paddle.fluid as fluid
C
chengjuntao 已提交
6462
        input = fluid.data(name="input",
6463 6464
                           shape=[2, 192, 64, 64],
                           dtype='float32')
C
chengjuntao 已提交
6465 6466
        rois = fluid.data(name="rois",
                          shape=[-1, 4],
6467
                          dtype='float32',
C
chengjuntao 已提交
6468 6469
                          lod_level=1)
        trans = fluid.data(name="trans",
6470 6471 6472 6473 6474
                           shape=[2, 384, 64, 64],
                           dtype='float32')
        x = fluid.layers.deformable_roi_pooling(input=input,
                                                rois=rois,
                                                trans=trans,
C
chengjuntao 已提交
6475
                                                no_trans=False,
6476
                                                spatial_scale=1.0,
C
chengjuntao 已提交
6477 6478 6479 6480
                                                group_size=(1, 1),
                                                pooled_height=8,
                                                pooled_width=8,
                                                part_size=(8, 8),
6481
                                                sample_per_part=4,
C
chengjuntao 已提交
6482 6483
                                                trans_std=0.1,
                                                position_sensitive=False)
C
cjt222 已提交
6484 6485
    """

6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'deformable_roi_pooling'
    )
    check_variable_and_dtype(
        rois, 'rois', ['float32', 'float64'], 'deformable_roi_pooling'
    )
    check_variable_and_dtype(
        trans, 'trans', ['float32', 'float64'], 'deformable_roi_pooling'
    )
    check_type(
        group_size, 'group_size', (list, tuple), 'deformable_roi_pooling'
    )
6498
    if part_size is not None:
6499 6500 6501
        check_type(
            part_size, 'part_size', (list, tuple), 'deformable_roi_pooling'
        )
6502

C
cjt222 已提交
6503
    input_channels = input.shape[1]
6504
    if position_sensitive is False:
C
cjt222 已提交
6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518
        output_channels = input_channels
    else:
        output_channels = input_channels / pooled_height / pooled_width

    if part_size is None:
        part_height = pooled_height
        part_width = pooled_width
        part_size = [part_height, part_width]
    part_size = utils.convert_to_list(part_size, 2, 'part_size')
    group_size = utils.convert_to_list(group_size, 2, 'group_size')
    helper = LayerHelper('deformable_psroi_pooling', **locals())
    dtype = helper.input_dtype()
    output = helper.create_variable_for_type_inference(dtype)
    top_count = helper.create_variable_for_type_inference(dtype='int32')
6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534
    helper.append_op(
        type="deformable_psroi_pooling",
        inputs={"Input": input, "ROIs": rois, "Trans": trans},
        outputs={"Output": output, "TopCount": top_count},
        attrs={
            "no_trans": no_trans,
            "spatial_scale": spatial_scale,
            "output_dim": output_channels,
            "group_size": group_size,
            "pooled_height": pooled_height,
            "pooled_width": pooled_width,
            "part_size": part_size,
            "sample_per_part": sample_per_part,
            "trans_std": trans_std,
        },
    )
C
cjt222 已提交
6535
    return output
6536 6537


6538
@deprecated(since="2.0.0", update_to="paddle.shard_index")
6539 6540
def shard_index(input, index_num, nshards, shard_id, ignore_value=-1):
    """
L
lilong12 已提交
6541 6542 6543 6544 6545 6546 6547 6548 6549
    Reset the values of `input` according to the shard it beloning to.
    Every value in `input` must be a non-negative integer, and
    the parameter `index_num` represents the integer above the maximum
    value of `input`. Thus, all values in `input` must be in the range
    [0, index_num) and each value can be regarded as the offset to the beginning
    of the range. The range is further split into multiple shards. Specifically,
    we first compute the `shard_size` according to the following formula,
    which represents the number of integers each shard can hold. So for the
    i'th shard, it can hold values in the range [i*shard_size, (i+1)*shard_size).
6550 6551
    ::

6552
        shard_size = (index_num + nshards - 1) // nshards
6553

L
lilong12 已提交
6554 6555 6556
    For each value `v` in `input`, we reset it to a new value according to the
    following formula:
    ::
6557

L
lilong12 已提交
6558 6559 6560 6561
        v = v - shard_id * shard_size if shard_id * shard_size <= v < (shard_id+1) * shard_size else ignore_value

    That is, the value `v` is set to the new offset within the range represented by the shard `shard_id`
    if it in the range. Otherwise, we reset it to be `ignore_value`.
6562 6563

    Args:
L
lilong12 已提交
6564 6565
        input (Tensor): Input tensor with data type int64 or int32. It's last dimension must be 1.
        index_num (int): An integer represents the integer above the maximum value of `input`.
6566 6567 6568
        nshards (int): The number of shards.
        shard_id (int): The index of the current shard.
        ignore_value (int): An integer value out of sharded index range.
6569 6570

    Returns:
L
lilong12 已提交
6571
        Tensor.
6572 6573 6574 6575

    Examples:
        .. code-block:: python

6576 6577 6578 6579 6580 6581 6582 6583
            import paddle
            label = paddle.to_tensor([[16], [1]], "int64")
            shard_label = paddle.shard_index(input=label,
                                             index_num=20,
                                             nshards=2,
                                             shard_id=0)
            print(shard_label)
            # [[-1], [1]]
6584
    """
H
hong 已提交
6585
    if in_dygraph_mode():
6586 6587 6588
        return _C_ops.shard_index(
            input, index_num, nshards, shard_id, ignore_value
        )
H
hong 已提交
6589

B
Baibaifan 已提交
6590
    check_variable_and_dtype(input, 'input', ['int64', 'int32'], 'shard_index')
6591 6592 6593
    op_type = 'shard_index'
    helper = LayerHelper(op_type, **locals())
    if shard_id < 0 or shard_id >= nshards:
6594 6595 6596
        raise ValueError(
            'The shard_id(%d) should be in [0, %d)' % (shard_id, nshards)
        )
6597 6598

    out = helper.create_variable_for_type_inference(dtype=input.dtype)
6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610
    helper.append_op(
        type=op_type,
        inputs={'X': [input]},
        outputs={'Out': out},
        attrs={
            'index_num': index_num,
            'nshards': nshards,
            'shard_id': shard_id,
            'ignore_value': ignore_value,
        },
        stop_gradient=True,
    )
6611
    return out
H
huangjun12 已提交
6612 6613 6614 6615


@templatedoc()
def hard_swish(x, threshold=6.0, scale=6.0, offset=3.0, name=None):
6616
    r"""
6617 6618 6619
    This operator implements the hard_swish activation function.
    Hard_swish is proposed in MobileNetV3, and performs better in computational stability and efficiency compared to swish function.
    For more details please refer to: https://arxiv.org/pdf/1905.02244.pdf
H
huangjun12 已提交
6620

6621
    The formula is as follows:
H
huangjun12 已提交
6622

6623
    .. math::
H
huangjun12 已提交
6624

6625
        out = \\frac{x * (min(max(0, x+offset), threshold))}{scale}
H
huangjun12 已提交
6626

6627 6628 6629 6630 6631 6632 6633 6634 6635
    In the above equation:

    ``threshold`` and ``scale`` should be positive, ``offset`` can be positive or negative. It is recommended to use default parameters.

    Args:
        x (Variable): Input feature, multi-dimensional Tensor. The data type should be float32 or float64.
        threshold (float, optional): The threshold in Relu function. Default: 6.0
        scale (float, optional): The scale factor. Default: 6.0
        offset (float, optional): The offset factor. Default: 3.0
6636 6637
        name (str, optional): The default value is None. Normally there is no need for user to set this property. For more information, please refer to :ref:`api_guide_Name`

6638 6639
    Returns:
        Variable: The output tensor with the same shape and data type as input.
6640 6641


6642
    Examples:
6643

6644
    .. code-block:: python
6645

6646
        import paddle.fluid as fluid
6647
        import paddle
6648
        import numpy as np
6649
        paddle.enable_static()
6650

6651
        DATATYPE='float32'
6652

6653
        x_data = np.array([i for i in range(1,5)]).reshape([1,1,4]).astype(DATATYPE)
6654

6655 6656
        x = fluid.data(name="x", shape=[None,1,4], dtype=DATATYPE)
        y = fluid.layers.hard_swish(x)
6657

6658 6659 6660 6661 6662
        place = fluid.CPUPlace()
        #place = fluid.CUDAPlace(0)
        exe = fluid.Executor(place)
        out, = exe.run(feed={'x':x_data}, fetch_list=[y.name])
        print(out)  # [[0.66666667, 1.66666667,3., 4.]]
H
huangjun12 已提交
6663
    """
J
Jiabin Yang 已提交
6664
    if _non_static_mode():
6665 6666 6667
        return _legacy_C_ops.hard_swish(
            x, 'threshold', threshold, 'scale', scale, 'offset', offset
        )
6668

6669 6670 6671
    check_variable_and_dtype(
        x, 'x', ['float16', 'float32', 'float64'], 'hard_swish'
    )
6672

H
huangjun12 已提交
6673 6674
    helper = LayerHelper('hard_swish', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
6675 6676 6677 6678 6679 6680
    helper.append_op(
        type='hard_swish',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'threshold': threshold, 'scale': scale, 'offset': offset},
    )
H
huangjun12 已提交
6681
    return out
R
ruri 已提交
6682 6683


K
Kaipeng Deng 已提交
6684 6685
@templatedoc()
def mish(x, threshold=20, name=None):
6686
    r"""
K
Kaipeng Deng 已提交
6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701
    This operator implements the mish activation function.
    Refer to `Mish: A Self Regularized Non-Monotonic Neural
    Activation Function <https://arxiv.org/abs/1908.08681>`_


    The formula is as follows if :attr:`threshold` is :code:`None` or negative:

    .. math::

        out = x * \\tanh(\\ln(1 + e^{x}))

    The formula is as follows if :attr:`threshold` is set as positive value:

    .. math::

6702 6703 6704 6705 6706
    out = \\begin{cases}
        x \\ast \\tanh(x), \\text{if } x > \\text{threshold} \\\\
        x \\ast \\tanh(e^{x}), \\text{if } x < -\\text{threshold} \\\\
        x \\ast \\tanh(\\ln(1 + e^{x})),  \\text{otherwise}
          \\end{cases}
K
Kaipeng Deng 已提交
6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727

    Args:
        x (Variable): Input feature, multi-dimensional Tensor. The data type
                      should be float16, float32 or float64.
        threshold (float|None): threshold for softplus in Mish operator.
                Approximate value of softplus will be used if absolute value
                of input is greater than :attr:threshold and :attr:threshold
                is set as positive value. For none or negative threshold,
                approximate value is not used. Default 20.
        name (str, optional): The default value is None. Normally there is no
                need for user to set this property. For more information, please
                refer to :ref:`api_guide_Name`

    Returns:
        Variable: The output tensor with the same shape and data type as input.


    Examples:

    .. code-block:: python

6728
        import paddle
K
Kaipeng Deng 已提交
6729 6730 6731
        import paddle.fluid as fluid
        import numpy as np

6732
        paddle.enable_static()
K
Kaipeng Deng 已提交
6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745
        DATATYPE='float32'

        x_data = np.array([i for i in range(1,5)]).reshape([1,1,4]).astype(DATATYPE)

        x = fluid.data(name="x", shape=[None,1,4], dtype=DATATYPE)
        y = fluid.layers.mish(x)

        place = fluid.CPUPlace()
        # place = fluid.CUDAPlace(0)
        exe = fluid.Executor(place)
        out, = exe.run(feed={'x':x_data}, fetch_list=[y.name])
        print(out)  # [[0.66666667, 1.66666667, 3., 4.]]
    """
6746
    if in_dygraph_mode():
6747
        return _C_ops.mish(x, threshold)
6748
    if _in_legacy_dygraph():
6749
        return _legacy_C_ops.mish(x, 'threshold', threshold)
6750

K
Kaipeng Deng 已提交
6751 6752
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'mish')
    check_type(threshold, 'threshold', (float, int), 'mish')
6753 6754 6755 6756 6757
    assert (
        threshold > 0
    ), "threshold of mish should be greater than 0, " "but got {}".format(
        threshold
    )
K
Kaipeng Deng 已提交
6758 6759 6760

    helper = LayerHelper('mish', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
6761 6762 6763 6764 6765 6766
    helper.append_op(
        type='mish',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'threshold': threshold},
    )
K
Kaipeng Deng 已提交
6767 6768 6769
    return out


6770
@deprecated(since="2.0.0", update_to="paddle.uniform")
6771
@templatedoc()
6772 6773 6774
def uniform_random(
    shape, dtype='float32', min=-1.0, max=1.0, seed=0, name=None
):
6775
    """
6776 6777
    This OP returns a Tensor filled with random values sampled from a uniform
    distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.
6778 6779 6780

    Examples:
    ::
6781

6782 6783
        Input:
          shape = [1, 2]
6784

6785 6786 6787 6788
        Output:
          result=[[0.8505902, 0.8397286]]

    Args:
6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801
        shape(list|tuple|Tensor): The shape of the output Tensor. If ``shape``
            is a list or tuple, the elements of it should be integers or Tensors
            (with the shape [1], and the data type int32 or int64). If ``shape``
            is a Tensor, it should be a 1-D Tensor(with the data type int32 or
            int64).
        dtype(str|np.dtype|core.VarDesc.VarType, optional): The data type of
            the output Tensor. Supported data types: float32, float64.
            Default is float32.
        min(float|int, optional): The lower bound on the range of random values
            to generate, ``min`` is included in the range. Default is -1.0.
        max(float|int, optional): The upper bound on the range of random values
            to generate, ``max`` is excluded in the range. Default is 1.0.
        seed(int, optional): Random seed used for generating samples. 0 means
6802 6803
            use a seed generated by the system. Note that if seed is not 0,
            this operator will always generate the same random numbers every
6804
            time. Default is 0.
6805 6806 6807
        name(str, optional): The default value is None. Normally there is no
            need for user to set this property. For more information, please
            refer to :ref:`api_guide_Name`.
6808

6809
    Returns:
6810 6811
        Tensor: A Tensor filled with random values sampled from a uniform
        distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.
6812

6813
    Raises:
6814 6815
        TypeError: If ``shape`` is not list, tuple, Tensor.
        TypeError: If ``dtype`` is not float32, float64.
6816

6817 6818 6819
    Examples:
        .. code-block:: python

6820
            import paddle
6821
            import paddle.fluid as fluid
6822
            paddle.enable_static()
6823 6824

            # example 1:
6825
            # attr shape is a list which doesn't contain Tensor.
6826
            result_1 = fluid.layers.uniform_random(shape=[3, 4])
6827 6828 6829
            # [[ 0.84524226,  0.6921872,   0.56528175,  0.71690357],
            #  [-0.34646994, -0.45116323, -0.09902662, -0.11397249],
            #  [ 0.433519,    0.39483607, -0.8660099,   0.83664286]]
6830 6831

            # example 2:
6832 6833 6834
            # attr shape is a list which contains Tensor.
            dim_1 = fluid.layers.fill_constant([1], "int64", 2)
            dim_2 = fluid.layers.fill_constant([1], "int32", 3)
6835
            result_2 = fluid.layers.uniform_random(shape=[dim_1, dim_2])
6836 6837
            # [[-0.9951253,   0.30757582, 0.9899647 ],
            #  [ 0.5864527,   0.6607096,  -0.8886161 ]]
6838 6839

            # example 3:
6840
            # attr shape is a Tensor, the data type must be int64 or int32.
6841
            var_shape = fluid.data(name='var_shape', shape=[2], dtype="int64")
6842
            result_3 = fluid.layers.uniform_random(var_shape)
6843 6844 6845 6846
            # if var_shape's value is [2, 3]
            # result_3 is:
            # [[-0.8517412,  -0.4006908,   0.2551912 ],
            #  [ 0.3364414,   0.36278176, -0.16085452]]
6847

6848 6849 6850
    """
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
6851

6852 6853
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
6854
        return _C_ops.uniform(
6855 6856 6857 6858 6859 6860 6861
            shape,
            dtype,
            float(min),
            float(max),
            seed,
            _current_expected_place(),
        )
6862
    elif _in_legacy_dygraph():
6863
        shape = utils.convert_shape_to_list(shape)
6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875
        return _legacy_C_ops.uniform_random(
            'shape',
            shape,
            'min',
            float(min),
            'max',
            float(max),
            'seed',
            seed,
            'dtype',
            dtype,
        )
6876

6877
    check_type(shape, 'shape', (list, tuple, Variable), 'uniform_random/rand')
6878 6879 6880
    check_dtype(
        dtype, 'dtype', ('float32', 'float64', 'uint16'), 'uniform_random/rand'
    )
6881 6882
    check_type(min, 'min', (float, int, Variable), 'uniform_random/rand')
    check_type(max, 'max', (float, int, Variable), 'uniform_random/rand')
6883 6884

    inputs = dict()
6885
    attrs = {'seed': seed, 'min': min, 'max': max, 'dtype': dtype}
6886 6887 6888
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='uniform_random/rand'
    )
6889

6890
    helper = LayerHelper("uniform_random", **locals())
6891
    out = helper.create_variable_for_type_inference(dtype)
6892 6893 6894
    helper.append_op(
        type="uniform_random", inputs=inputs, attrs=attrs, outputs={"Out": out}
    )
6895
    utils.try_set_static_shape_tensor(out, shape)
6896
    return out
myq406450149's avatar
myq406450149 已提交
6897 6898 6899 6900 6901 6902 6903


def unbind(input, axis=0):
    """
    Removes a tensor dimension, then split the input tensor into multiple sub-Tensors.
    Args:
        input (Variable): The input variable which is an N-D Tensor, data type being float32, float64, int32 or int64.
6904

myq406450149's avatar
myq406450149 已提交
6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929
        axis (int32|int64, optional): A scalar with type ``int32|int64`` shape [1]. The dimension along which to unbind. If :math:`axis < 0`, the
            dimension to unbind along is :math:`rank(input) + axis`. Default is 0.
    Returns:
        list(Variable): The list of segmented Tensor variables.

    Example:
        .. code-block:: python
            import paddle
            # input is a variable which shape is [3, 4, 5]
            input = paddle.fluid.data(
                 name="input", shape=[3, 4, 5], dtype="float32")
            [x0, x1, x2] = paddle.tensor.unbind(input, axis=0)
            # x0.shape [4, 5]
            # x1.shape [4, 5]
            # x2.shape [4, 5]
            [x0, x1, x2, x3] = paddle.tensor.unbind(input, axis=1)
            # x0.shape [3, 5]
            # x1.shape [3, 5]
            # x2.shape [3, 5]
            # x3.shape [3, 5]

    """
    helper = LayerHelper("unbind", **locals())
    check_type(input, 'input', (Variable), 'unbind')
    dtype = helper.input_dtype()
6930 6931 6932
    check_dtype(
        dtype, 'unbind', ['float32', 'float64', 'int32', 'int64'], 'unbind'
    )
myq406450149's avatar
myq406450149 已提交
6933
    if not isinstance(axis, (int)):
6934 6935 6936
        raise TypeError(
            "The type of 'axis'  must be int, but received %s." % (type(axis))
        )
myq406450149's avatar
myq406450149 已提交
6937 6938 6939 6940 6941 6942 6943 6944 6945 6946
    if isinstance(axis, np.generic):
        axis = np.asscalar(axis)
    input_shape = input.shape
    axis_ = axis if axis >= 0 else len(input_shape) + axis
    num = input_shape[axis_]
    outs = [
        helper.create_variable_for_type_inference(dtype=helper.input_dtype())
        for i in range(num)
    ]

6947 6948 6949 6950 6951 6952
    helper.append_op(
        type="unbind",
        inputs={"X": input},
        outputs={"Out": outs},
        attrs={"axis": axis},
    )
myq406450149's avatar
myq406450149 已提交
6953
    return outs