nn.py 305.8 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
    'fc',
    'embedding',
    'linear_chain_crf',
    'crf_decoding',
    'cos_sim',
    'conv2d',
    'softmax',
    'pool2d',
    'batch_norm',
    'reduce_mean',
Z
zhoukunsheng 已提交
76 77
    'reduce_all',
    'reduce_any',
X
Xin Pan 已提交
78 79 80 81 82 83 84 85 86 87
    'dropout',
    'split',
    'ctc_greedy_decoder',
    'l2_normalize',
    'matmul',
    'topk',
    'im2sequence',
    'row_conv',
    'multiplex',
    'layer_norm',
D
dengkaipeng 已提交
88
    'spectral_norm',
X
Xin Pan 已提交
89 90 91 92 93 94 95 96
    'smooth_l1',
    'one_hot',
    'autoincreased_step_counter',
    'unsqueeze',
    'lod_reset',
    'pad',
    'image_resize',
    'resize_bilinear',
K
Kaipeng Deng 已提交
97
    'resize_trilinear',
98
    'resize_nearest',
X
Xin Pan 已提交
99 100 101
    'relu',
    'log',
    'prelu',
Z
zhoukunsheng 已提交
102
    'unique',
103
    'unique_with_counts',
X
Xin Pan 已提交
104 105 106 107 108 109 110 111 112 113 114 115
    'elementwise_add',
    'elementwise_div',
    'elementwise_sub',
    'elementwise_mul',
    'gaussian_random',
    'sampling_id',
    'sum',
    'shape',
    'clip',
    'clip_by_norm',
    'mean',
    'mul',
M
minqiyang 已提交
116
    'hash',
D
dengkaipeng 已提交
117
    'grid_sampler',
G
gmcather 已提交
118
    'log_loss',
Q
Qiao Longfei 已提交
119
    'bilinear_tensor_product',
C
chengduo 已提交
120 121
    'merge_selected_rows',
    'get_tensor_from_selected_rows',
122
    'temporal_shift',
S
sneaxiy 已提交
123
    'py_func',
R
ruri 已提交
124
    'pixel_shuffle',
125
    'fsp_matrix',
H
heqiaozhi 已提交
126
    'continuous_value_model',
Z
zhoukunsheng 已提交
127
    'where',
Z
zhoukunsheng 已提交
128
    'sign',
129
    'unfold',
C
cjt222 已提交
130
    'deformable_roi_pooling',
131
    'shard_index',
H
huangjun12 已提交
132
    'hard_swish',
K
Kaipeng Deng 已提交
133
    'mish',
G
Guo Sheng 已提交
134
    'gather_tree',
135
    'uniform_random',
myq406450149's avatar
myq406450149 已提交
136
    'unbind',
Y
Yu Yang 已提交
137 138
]

139
OP_NAMEMAPPING = {
140 141 142 143 144 145 146 147
    '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 已提交
148
    'elementwise_mod': 'remainder',
149 150
}

Y
Yu Yang 已提交
151

152 153
def _get_reduce_dim(dim, input):
    """
154
    Internal function for reduce_sum, reduce_mean, reduce_prod.
155 156 157 158 159 160 161 162 163
    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(
164 165 166 167
                "The type of dim must be int, list, tuple or range, but received {}".format(
                    type(axis)
                )
            )
168 169 170 171 172 173 174 175 176 177
    if dim is None:
        dim = []
    if dim == [] or len(dim) == len(input.shape):
        reduce_all = True
    else:
        reduce_all = False

    return reduce_all, dim


178
@dygraph_only
179 180 181
def _elementwise_op_in_dygraph(
    x, y, axis=-1, act=None, use_mkldnn=False, op_name=None
):
182 183 184 185
    def is_inplace(op_name):
        return op_name[-1] == "_"

    if op_name not in OP_NAMEMAPPING.keys() or axis != -1:
186
        op = getattr(_legacy_C_ops, op_name)
187 188 189
        out = op(x, y, 'axis', axis, 'use_mkldnn', use_mkldnn)
    else:
        if in_dygraph_mode():
190 191
            op = getattr(
                _C_ops,
192 193
                OP_NAMEMAPPING[op_name] if not is_inplace(op_name) else op_name,
            )
194 195 196
            out = op(x, y)

        if _in_legacy_dygraph():
197
            op = getattr(_legacy_C_ops, op_name)
198
            out = op(x, y, 'axis', axis, 'use_mkldnn', use_mkldnn)
199 200 201 202 203 204 205 206 207 208 209 210 211 212
    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,
):
213
    r"""
214 215
    :api_attr: Static Graph

216
    **Fully Connected Layer**
Y
Yu Yang 已提交
217

218 219 220
    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,
221
    which represents a fully connected weight matrix from each input unit to
222 223 224 225
    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`
226
    is not None, a bias variable will be created and added to the output.
227
    Finally, if :attr:`act` is not None, it will be applied to the output as well.
C
caoying03 已提交
228

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

231 232 233 234
    .. math::

        Out = Act({XW + b})

235
    When the input is a list of Tensor(or LoDTensor):
236 237 238

    .. math::

239
        Out = Act({\sum_{i=0}^{N-1}X_iW_i + b})
240 241 242

    In the above equation:

243 244 245
    * :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 已提交
246
    * :math:`b`: The bias parameter created by this layer (if needed).
247
    * :math:`Act`: The activation function.
248
    * :math:`Out`: The output Tensor.
249 250 251

    .. code-block:: text

252 253 254 255 256 257 258 259 260 261 262 263 264 265
        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:
266 267 268 269 270 271 272 273 274 275 276 277 278
            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 已提交
279
    Args:
280 281 282
        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 已提交
283
        size(int): The number of output units in this layer, which also means the feature size of output
284 285
            Tensor(or LoDTensor).
        num_flatten_dims (int): The fc layer can accept an input Tensor with more than
R
ranqiu 已提交
286
            two dimensions. If this happens, the multidimensional tensor will first be flattened
287 288
            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 已提交
289
            dimensions will be flatten to form the first dimension of the final matrix (height of
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
            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.
305 306

    Raises:
307
        ValueError: If dimensions of the input Tensor is less than 2.
308 309 310 311

    Examples:
        .. code-block:: python

312
          import paddle.fluid as fluid
313 314
          import paddle
          paddle.enable_static()
315
          # when input is single tensor
316
          data = fluid.data(name="data", shape=[-1, 32], dtype="float32")
317
          fc = fluid.layers.fc(input=data, size=1000, act="tanh")
318 319

          # when input are multiple tensors
320 321
          data_1 = fluid.data(name="data_1", shape=[-1, 32], dtype="float32")
          data_2 = fluid.data(name="data_2", shape=[-1, 36], dtype="float32")
322
          fc = fluid.layers.fc(input=[data_1, data_2], size=1000, act="tanh")
Y
Yu Yang 已提交
323
    """
C
caoying03 已提交
324
    helper = LayerHelper("fc", **locals())
325
    check_type(input, 'input', (list, tuple, Variable), 'fc')
326 327
    if isinstance(input, (list, tuple)):
        for i, input_x in enumerate(input):
328
            check_type(input_x, 'input[' + str(i) + ']', Variable, 'fc')
Y
Yu Yang 已提交
329
    dtype = helper.input_dtype()
330 331 332
    check_dtype(
        dtype, 'input', ['float16', 'uint16', 'float32', 'float64'], 'fc'
    )
Y
Yu Yang 已提交
333
    mul_results = []
334 335
    for input_var, param_attr in helper.iter_inputs_and_params():
        input_shape = input_var.shape
336 337
        if num_flatten_dims == -1:
            num_flatten_dims = len(input_shape) - 1
Y
Yu Yang 已提交
338 339 340
        param_shape = [
            reduce(lambda a, b: a * b, input_shape[num_flatten_dims:], 1)
        ] + [size]
Y
ying 已提交
341

342 343 344
        w = helper.create_parameter(
            attr=param_attr, shape=param_shape, dtype=dtype, is_bias=False
        )
X
Xin Pan 已提交
345
        tmp = helper.create_variable_for_type_inference(dtype)
346 347 348 349 350 351
        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},
        )
352 353 354 355
        mul_results.append(tmp)

    if len(mul_results) == 1:
        pre_bias = mul_results[0]
356
    else:
X
Xin Pan 已提交
357
        pre_bias = helper.create_variable_for_type_inference(dtype)
358 359 360 361 362 363
        helper.append_op(
            type="sum",
            inputs={"X": mul_results},
            outputs={"Out": pre_bias},
            attrs={"use_mkldnn": False},
        )
364 365 366 367
    # 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 已提交
368 369


T
tangwei12 已提交
370
@deprecated(since="2.0.0", update_to="paddle.nn.functional.embedding")
371 372 373 374 375 376 377 378 379
def embedding(
    input,
    size,
    is_sparse=False,
    is_distributed=False,
    padding_idx=None,
    param_attr=None,
    dtype='float32',
):
380
    r"""
381
    :api_attr: Static Graph
382

383 384 385 386 387 388 389 390 391 392 393 394
    **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.

395
    **Note:** The id in :attr:`input` must satisfy :math:`0 =< id < size[0]` ,
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
    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]],
413

414 415 416 417
                        [[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.
418

419
        Case 2:
420

421 422 423 424 425 426 427 428 429 430 431 432 433 434
        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 已提交
435 436

    Args:
437 438 439 440 441 442
        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
443
            affects the performance of the backwards gradient update. It is recommended to set
444
            True because sparse update is faster. But some optimizer does not support sparse update,
445
            such as :ref:`api_fluid_optimizer_AdadeltaOptimizer` , :ref:`api_fluid_optimizer_AdamaxOptimizer` ,
446 447 448 449 450
            :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.
451
        padding_idx(int|long|None): padding_idx needs to be in the interval [-vocab_size, vocab_size).
452 453 454 455 456 457
            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,
458
            user-defined or pre-trained word vectors can be loaded with the :attr:`param_attr` parameter.
459
            The local word vector needs to be transformed into numpy format, and the shape of local word
T
tianshuo78520a 已提交
460
            vector should be consistent with :attr:`size` . Then :ref:`api_fluid_initializer_NumpyArrayInitializer`
461 462 463
            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 已提交
464

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

468 469
    Examples:
        .. code-block:: python
Y
Yu Yang 已提交
470

B
bdzhuxiaoning 已提交
471
          import paddle.fluid as fluid
472
          import numpy as np
473 474
          import paddle
          paddle.enable_static()
475

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

T
tianshuo78520a 已提交
478
          # example 1
479 480 481 482 483 484 485 486 487
          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)
488
          emb_2 = fluid.layers.embedding(input=data, size=(128, 100), param_attr=w_param_attrs, dtype='float32')
Y
Yu Yang 已提交
489 490 491
    """

    helper = LayerHelper('embedding', **locals())
492 493 494 495 496 497 498 499 500
    check_variable_and_dtype(
        input, 'input', ['int64'], 'fluid.layers.embedding'
    )
    check_dtype(
        dtype,
        'dtype',
        ['uint16', 'float16', 'float32', 'float64'],
        'fluid.layers.embedding',
    )
501 502 503 504 505 506 507 508 509

    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

510 511 512
    w = helper.create_parameter(
        attr=helper.param_attr, shape=size, dtype=dtype, is_bias=False
    )
X
Xin Pan 已提交
513
    tmp = helper.create_variable_for_type_inference(dtype)
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531
    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 已提交
532 533 534
    return tmp


535 536 537 538 539 540 541 542 543 544 545
def _pull_sparse(
    input,
    size,
    table_id,
    accessor_class,
    name="embedding",
    ctr_label_name="",
    padding_id=0,
    dtype='float32',
    scale_sparse_grad=True,
):
546
    r"""
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 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591
    **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
592
        'is_distributed': True,
593 594
    }
    # this is only for compatible with embedding op
595 596 597 598 599 600 601 602 603
    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,
    )
604 605 606 607 608
    if len(outs) == 1:
        return outs[0]
    return outs


609 610 611 612 613 614 615 616 617 618 619
def _pull_sparse_v2(
    input,
    size,
    table_id,
    accessor_class,
    name="embedding",
    ctr_label_name="",
    padding_id=0,
    dtype='float32',
    scale_sparse_grad=True,
):
620
    r"""
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 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665
    **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
666
        'is_distributed': True,
667 668
    }
    # this is only for compatible with embedding op
669 670 671 672 673 674 675 676 677
    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,
    )
678
    if len(outs) == 1:
Y
yaoxuefeng 已提交
679 680 681 682
        return outs[0]
    return outs


683 684 685
def _pull_gpups_sparse(
    input, size, dtype='float32', is_distributed=False, is_sparse=False
):
Y
yaoxuefeng 已提交
686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718
    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
	    float32 now.

    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(
719 720 721
            "GpuPS only support float type embedding now, and your type is: "
            + dtype
        )
Y
yaoxuefeng 已提交
722 723 724 725 726 727
    helper.input_dtype()
    inputs = helper.multiple_input()
    outs = [
        helper.create_variable_for_type_inference(dtype)
        for i in range(len(inputs))
    ]
728 729 730 731 732 733 734 735 736 737 738 739 740
    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 已提交
741
    if len(outs) == 1:
742 743 744 745
        return outs[0]
    return outs


746 747 748
def _pull_box_sparse(
    input, size, dtype='float32', is_distributed=False, is_sparse=False
):
749
    r"""
H
hutuxian 已提交
750 751 752 753 754 755 756
    **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:
757
        input(Variable|list of Variable): Input is a Tensor<int64> Variable, which
H
hutuxian 已提交
758
            contains the IDs information.
759
        size(int): The embedding size parameter, which indicates the size of
H
hutuxian 已提交
760
            each embedding vector respectively.
761
        dtype(str): The dtype refers to the data type of output tensor. Only supports
H
hutuxian 已提交
762 763 764 765 766 767 768 769 770 771 772
	    float32 now.

    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)
773
          emb = fluid.layers.pull_box_sparse(input=data, size=[11])
H
hutuxian 已提交
774 775 776 777
    """
    helper = LayerHelper('pull_box_sparse', **locals())
    if dtype != 'float32':
        raise ValueError(
778 779 780
            "BoxPS only support float type embedding now, and your type is: "
            + dtype
        )
H
hutuxian 已提交
781 782 783 784 785 786
    helper.input_dtype()
    inputs = helper.multiple_input()
    outs = [
        helper.create_variable_for_type_inference(dtype)
        for i in range(len(inputs))
    ]
787 788 789 790 791 792 793 794 795 796 797 798 799
    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 已提交
800 801 802 803 804
    if len(outs) == 1:
        return outs[0]
    return outs


Y
yuyang18 已提交
805
@templatedoc()
806
def linear_chain_crf(input, label, param_attr=None, length=None):
Y
yuyang18 已提交
807
    """
808 809
    :api_attr: Static Graph

Y
yuyang18 已提交
810 811 812 813 814
    Linear Chain CRF.

    ${comment}

    Args:
815
        input(${emission_type}): ${emission_comment}
Y
yuyang18 已提交
816
        label(${label_type}): ${label_comment}
817
        Length(${length_type}): ${length_comment}
818
        param_attr(ParamAttr): The attribute of the learnable parameter for transition parameter.
Y
yuyang18 已提交
819 820

    Returns:
D
dzhwinter 已提交
821 822
        output(${emission_exps_type}): ${emission_exps_comment} \n
        output(${transition_exps_type}): ${transition_exps_comment} \n
823
        output(${log_likelihood_type}): ${log_likelihood_comment} \n
Y
yuyang18 已提交
824

J
JesseyXujin 已提交
825 826 827
    Examples:
        .. code-block:: python

828 829
            import paddle.fluid as fluid
            import numpy as np
830 831
            import paddle
            paddle.enable_static()
832 833 834 835 836

            #define net structure, using LodTensor
            train_program = fluid.Program()
            startup_program = fluid.Program()
            with fluid.program_guard(train_program, startup_program):
837 838
                input_data = fluid.data(name='input_data', shape=[-1,10], dtype='float32')
                label = fluid.data(name='label', shape=[-1,1], dtype='int')
839 840 841 842 843 844
                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',
845
                    learning_rate=0.01))
846 847 848
            use_cuda = False
            place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
            exe = fluid.Executor(place)
849
            exe.run(startup_program)
850 851 852 853 854
            #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])
855
            print(loss)
856 857 858 859 860

            #define net structure, using padding
            train_program = fluid.Program()
            startup_program = fluid.Program()
            with fluid.program_guard(train_program, startup_program):
861 862 863
                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')
864 865 866 867 868 869
                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 已提交
870
                     name='crfw',
871 872 873 874 875 876
                     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 已提交
877

878 879 880
            #define data, using padding
            cc=np.random.rand(4,10,10).astype('float32')
            dd=np.random.rand(4,10,1).astype('int64')
881
            ll=np.array([[3],[3],[4],[2]])
882 883
            feed2 = {'input_data2':cc,'label2':dd,'length':ll}
            loss2= exe.run(train_program,feed=feed2, fetch_list=[crf_cost2])
884
            print(loss2)
885 886 887 888 889
            #[array([[ 7.8902354],
            #        [ 7.3602567],
            #        [ 10.004011],
            #        [ 5.86721  ]], dtype=float32)]

890 891 892
            #you can use find_var to get transition parameter.
            transition=np.array(fluid.global_scope().find_var('crfw').get_tensor())
            print(transition)
893

Y
yuyang18 已提交
894
    """
895 896 897
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'linear_chain_crf'
    )
898
    check_variable_and_dtype(label, 'label', ['int64'], 'linear_chain_crf')
Y
Yu Yang 已提交
899
    helper = LayerHelper('linear_chain_crf', **locals())
900
    size = input.shape[2] if length else input.shape[1]
901 902 903 904 905
    transition = helper.create_parameter(
        attr=helper.param_attr,
        shape=[size + 2, size],
        dtype=helper.input_dtype(),
    )
X
Xin Pan 已提交
906
    alpha = helper.create_variable_for_type_inference(
907 908
        dtype=helper.input_dtype()
    )
X
Xin Pan 已提交
909
    emission_exps = helper.create_variable_for_type_inference(
910 911
        dtype=helper.input_dtype()
    )
X
Xin Pan 已提交
912
    transition_exps = helper.create_variable_for_type_inference(
913 914
        dtype=helper.input_dtype()
    )
X
Xin Pan 已提交
915
    log_likelihood = helper.create_variable_for_type_inference(
916 917
        dtype=helper.input_dtype()
    )
918 919 920
    this_inputs = {
        "Emission": [input],
        "Transition": transition,
921
        "Label": [label],
922 923
    }
    if length:
924
        this_inputs['Length'] = [length]
925 926 927 928 929 930 931 932 933 934
    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 已提交
935 936 937 938

    return log_likelihood


W
wopeizl 已提交
939
@templatedoc()
940
def crf_decoding(input, param_attr, label=None, length=None):
W
wopeizl 已提交
941
    """
942
    :api_attr: Static Graph
943

W
wopeizl 已提交
944
    ${comment}
Y
yi.wu 已提交
945

W
wopeizl 已提交
946
    Args:
947
        input(Tensor): ${emission_comment}
Y
yi.wu 已提交
948

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

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

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

W
wopeizl 已提交
957
    Returns:
958
        Tensor: ${viterbi_path_comment}
Y
yi.wu 已提交
959

W
wopeizl 已提交
960 961
    Examples:
        .. code-block:: python
Y
yi.wu 已提交
962

963 964
           import paddle
           paddle.enable_static()
965 966 967

           # LoDTensor-based example
           num_labels = 10
968 969 970
           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)
971

972 973 974 975
           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"))
976 977 978

           # Common tensor example
           num_labels, max_len = 10, 20
979 980 981 982
           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,
983
                                      num_flatten_dims=2)
984

985 986 987 988
           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 已提交
989
    """
990 991 992
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'crf_decoding'
    )
W
wopeizl 已提交
993 994 995
    helper = LayerHelper('crf_decoding', **locals())
    transition = helper.get_parameter(param_attr.name)
    viterbi_path = helper.create_variable_for_type_inference(
996 997
        dtype=core.VarDesc.VarType.INT64
    )
998 999 1000
    inputs = {"Emission": [input], "Transition": transition, "Label": label}
    if length:
        inputs['Length'] = length
1001 1002 1003 1004 1005
    helper.append_op(
        type='crf_decoding',
        inputs=inputs,
        outputs={"ViterbiPath": [viterbi_path]},
    )
Y
Yu Yang 已提交
1006

W
wopeizl 已提交
1007
    return viterbi_path
Y
Yu Yang 已提交
1008 1009


Y
yi.wu 已提交
1010
@templatedoc()
F
fengjiayi 已提交
1011
def cos_sim(X, Y):
Y
Yu Yang 已提交
1012
    """
Y
yi.wu 已提交
1013 1014 1015
    ${comment}

    Args:
N
Noel 已提交
1016 1017
        X (Tensor): ${x_comment}.
        Y (Tensor): ${y_comment}.
F
fengjiayi 已提交
1018

Y
yi.wu 已提交
1019
    Returns:
N
Noel 已提交
1020
        A Tensor representing the output of cosine(X, Y).
L
lvmengsi 已提交
1021 1022 1023 1024

    Examples:
        .. code-block:: python

N
Noel 已提交
1025 1026 1027 1028 1029 1030 1031
            import paddle

            x = paddle.rand(shape=[3, 7], dtype='float32')
            y = paddle.rand(shape=[1, 7], dtype='float32')
            out = paddle.fluid.layers.cos_sim(x, y)
            print(out)

Y
Yu Yang 已提交
1032
    """
1033 1034
    check_variable_and_dtype(X, 'X', ['float32'], 'cos_sim')
    check_variable_and_dtype(Y, 'Y', ['float32'], 'cos_sim')
F
fengjiayi 已提交
1035
    helper = LayerHelper('cos_sim', **locals())
X
Xin Pan 已提交
1036 1037 1038
    out = helper.create_variable_for_type_inference(dtype=X.dtype)
    xnorm = helper.create_variable_for_type_inference(dtype=X.dtype)
    ynorm = helper.create_variable_for_type_inference(dtype=X.dtype)
1039 1040 1041 1042 1043
    helper.append_op(
        type='cos_sim',
        inputs={'X': [X], 'Y': [Y]},
        outputs={'Out': [out], 'XNorm': [xnorm], 'YNorm': [ynorm]},
    )
Y
Yu Yang 已提交
1044 1045 1046
    return out


1047
@deprecated(since="2.0.0", update_to="paddle.nn.functional.dropout")
1048 1049 1050 1051 1052 1053 1054 1055
def dropout(
    x,
    dropout_prob,
    is_test=None,
    seed=None,
    name=None,
    dropout_implementation="downgrade_in_infer",
):
1056
    """
1057

1058 1059 1060 1061
    Computes dropout.

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

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

1068
    Args:
L
lvmengsi 已提交
1069
        x (Variable): The input tensor variable. The data type is float16 or float32 or float64.
1070
        dropout_prob (float): Probability of setting units to zero.
1071
        is_test (bool): A flag indicating whether it is in test phrase or not.
1072
                        Default None, in dynamic graph, it use global tracer mode; in static graph, it means False.
1073 1074 1075
        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 已提交
1076
                    units will be dropped. DO NOT use a fixed seed in training.Default: None.
1077 1078
        name (str|None): A name for this layer(optional). If set None, the layer
                         will be named automatically.
H
haowang101779990 已提交
1079 1080
        dropout_implementation(string): ['downgrade_in_infer'(default)|'upscale_in_train']

P
phlrain 已提交
1081
                                        1. downgrade_in_infer(default), downgrade the outcome at inference
H
haowang101779990 已提交
1082 1083

                                           - train: out = input * mask
C
ceci3 已提交
1084
                                           - inference: out = input * (1.0 - dropout_prob)
H
haowang101779990 已提交
1085 1086 1087

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

H
haowang101779990 已提交
1090 1091
                                           - train: out = input * mask / ( 1.0 - dropout_prob )
                                           - inference: out = input
P
phlrain 已提交
1092

H
haowang101779990 已提交
1093 1094
                                           (mask is a tensor same shape with input, value is 0 or 1
                                           ratio of 0 is dropout_prob)
1095

M
minqiyang 已提交
1096

1097
    Returns:
L
lvmengsi 已提交
1098
        A Variable holding Tensor representing the dropout, has same shape and data type with `x`.
1099 1100

    Examples:
1101

1102 1103
        .. code-block:: python

1104
            import paddle
1105
            import paddle.fluid as fluid
1106

1107
            paddle.enable_static()
L
lvmengsi 已提交
1108
            x = fluid.data(name="data", shape=[None, 32, 32], dtype="float32")
T
tianshuo78520a 已提交
1109
            dropped = fluid.layers.dropout(x, dropout_prob=0.5)
1110
    """
1111 1112
    if not isinstance(dropout_prob, (float, int, Variable)):
        raise TypeError(
1113 1114
            "dropout_prob argument should be a number(int|float) or Variable"
        )
1115
    # fast return for p == 0
1116
    if isinstance(dropout_prob, (int, float)) and dropout_prob == 0:
1117
        return x
1118

J
Jiabin Yang 已提交
1119
    if _non_static_mode():
1120 1121 1122
        if (
            seed is None or seed == 0
        ) and default_main_program().random_seed != 0:
1123
            seed = default_main_program().random_seed
1124 1125
        if is_test is None:
            is_test = not _dygraph_tracer()._train_mode
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138
        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,
        )
1139
        return out
1140

W
wanghuancoder 已提交
1141 1142 1143
    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
1144 1145
        if isinstance(dropout_prob, Variable) and not dropout_prob.shape != [1]:
            raise TypeError(
1146 1147 1148 1149
                "Required dropout_prob.shape == [1] if type(dropout_prob) is Variable, but received dropout_prob.shape = {}".format(
                    dropout_prob.shape
                )
            )
W
wanghuancoder 已提交
1150 1151 1152 1153 1154 1155 1156 1157 1158
        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 已提交
1159
    helper = LayerHelper('dropout', **locals())
1160 1161 1162
    check_variable_and_dtype(
        x, 'x', ['float16', 'float32', 'float64'], 'dropout'
    )
1163

X
Xin Pan 已提交
1164 1165
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
    mask = helper.create_variable_for_type_inference(
1166 1167
        dtype=core.VarDesc.VarType.UINT8, stop_gradient=True
    )
C
chengduo 已提交
1168

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

1171 1172 1173 1174 1175 1176
    helper.append_op(
        type='dropout',
        inputs={'X': [x]},
        outputs={'Out': [out], 'Mask': [mask]},
        attrs=attrs,
    )
1177 1178 1179
    return out


1180
@deprecated(since="2.0.0", update_to="paddle.nn.functional.softmax")
1181
def softmax(input, use_cudnn=True, name=None, axis=-1):
1182
    r"""
1183
    This operator implements the softmax layer. The calculation process is as follows:
1184

1185
    1. The dimension :attr:`axis` of the ``input`` will be permuted to the last.
1186

1187 1188 1189 1190 1191 1192 1193
    2. Then the input tensor will be logically flattened to a 2-D matrix. The matrix's
    second dimension(row length) is the same as the dimension :attr:`axis` of the input
    tensor, and the first dimension(column length) is the product of all other
    dimensions of the input tensor. For each row of the matrix, the softmax operator
    squashes the K-dimensional(K is the width of the matrix, which is also the size
    of the input tensor's dimension :attr:`axis`) vector of arbitrary real values to a
    K-dimensional vector of real values in the range [0, 1] that add up to 1.
1194

1195
    3. After the softmax operation is completed, the inverse operations of steps 1 and 2
1196
    are performed to restore the two-dimensional matrix to the same dimension as the ``input``.
1197

1198 1199 1200 1201 1202
    It computes the exponential of the given dimension and the sum of exponential
    values of all the other dimensions in the K-dimensional vector input.
    Then the ratio of the exponential of the given dimension and the sum of
    exponential values of all the other dimensions is the output of the softmax
    operator.
1203

1204
    For each row :math:`i` and each column :math:`j` in the matrix, we have:
1205

1206
    .. math::
1207

N
Noel 已提交
1208
        Out[i, j] = \\frac{\\exp(X[i, j])}{\\sum_j(exp(X[i, j])}
1209

1210
    Example:
1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254

    .. code-block:: text

        Case 1:
          Input:
            X.shape = [2, 3, 4]
            X.data = [[[2.0, 3.0, 4.0, 5.0],
                       [3.0, 4.0, 5.0, 6.0],
                       [7.0, 8.0, 8.0, 9.0]],
                      [[1.0, 2.0, 3.0, 4.0],
                       [5.0, 6.0, 7.0, 8.0],
                       [6.0, 7.0, 8.0, 9.0]]]

          Attrs:
            axis = -1

          Output:
            Out.shape = [2, 3, 4]
            Out.data = [[[0.0320586 , 0.08714432, 0.23688282, 0.64391426],
                         [0.0320586 , 0.08714432, 0.23688282, 0.64391426],
                         [0.07232949, 0.19661193, 0.19661193, 0.53444665]],
                        [[0.0320586 , 0.08714432, 0.23688282, 0.64391426],
                         [0.0320586 , 0.08714432, 0.23688282, 0.64391426],
                         [0.0320586 , 0.08714432, 0.23688282, 0.64391426]]]

        Case 2:
          Input:
            X.shape = [2, 3, 4]
            X.data = [[[2.0, 3.0, 4.0, 5.0],
                       [3.0, 4.0, 5.0, 6.0],
                       [7.0, 8.0, 8.0, 9.0]],
                      [[1.0, 2.0, 3.0, 4.0],
                       [5.0, 6.0, 7.0, 8.0],
                       [6.0, 7.0, 8.0, 9.0]]]
          Attrs:
            axis = 1

          Output:
            Out.shape = [2, 3, 4]
            Out.data = [[[0.00657326, 0.00657326, 0.01714783, 0.01714783],
                         [0.01786798, 0.01786798, 0.04661262, 0.04661262],
                         [0.97555875, 0.97555875, 0.93623955, 0.93623955]],
                        [[0.00490169, 0.00490169, 0.00490169, 0.00490169],
                         [0.26762315, 0.26762315, 0.26762315, 0.26762315],
1255
                         [0.72747516, 0.72747516, 0.72747516, 0.72747516]]]
1256

Q
qiaolongfei 已提交
1257
    Args:
N
Noel 已提交
1258
        input (Tensor): The input tensor. A multi-dimension ``Tensor`` with type float32 or float64.
1259
        use_cudnn (bool, optional): Use cudnn kernel or not, it is valid only when the cudnn \
G
GaoWei8 已提交
1260
            library is installed. To improve performance, set use_cudnn to True by default.
1261
        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` . Default: None.
C
chengduo 已提交
1262
            will be named automatically. Default: None.
1263
        axis (int, optional): The index of dimension to perform softmax calculations, it should
D
dengkaipeng 已提交
1264
            be in range :math:`[-1, rank - 1]`, while :math:`rank` is the rank of
N
Noel 已提交
1265
            input tensor. Default: -1. -1 means the last dimension.
Q
qiaolongfei 已提交
1266 1267

    Returns:
N
Noel 已提交
1268
        Tensor: ``Tensor`` indicates the output of softmax. The data type and shape are the same as ``input`` .
Q
qiaolongfei 已提交
1269 1270 1271 1272 1273

    Examples:

        .. code-block:: python

N
Noel 已提交
1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
            import paddle
            import paddle.nn.functional as F

            x = paddle.to_tensor([[[2.0, 3.0, 4.0, 5.0],
                                [3.0, 4.0, 5.0, 6.0],
                                [7.0, 8.0, 8.0, 9.0]],
                                [[1.0, 2.0, 3.0, 4.0],
                                [5.0, 6.0, 7.0, 8.0],
                                [6.0, 7.0, 8.0, 9.0]]], dtype='float32')
            y = F.softmax(x, axis=1)
            print(y)
            # [[[0.00657326, 0.00657326, 0.01714783, 0.01714783],
            #   [0.01786798, 0.01786798, 0.04661262, 0.04661262],
            #   [0.97555870, 0.97555870, 0.93623954, 0.93623954]],
            #  [[0.00490169, 0.00490169, 0.00490169, 0.00490169],
            #   [0.26762316, 0.26762316, 0.26762316, 0.26762316],
            #   [0.72747517, 0.72747517, 0.72747517, 0.72747517]]]
Q
qiaolongfei 已提交
1291 1292

    """
1293

H
hong 已提交
1294
    if in_dygraph_mode():
1295
        return _C_ops.softmax(input, axis)
H
hong 已提交
1296

J
Jiabin Yang 已提交
1297
    if _non_static_mode():
1298 1299 1300
        return _legacy_C_ops.softmax(
            input, 'axis', axis, 'use_cudnn', use_cudnn
        )
1301 1302 1303

    inputs = {"X": [input]}
    attrs = {"axis": axis, "use_cudnn": use_cudnn}
1304

1305
    helper = LayerHelper('softmax', **locals())
1306 1307 1308
    check_variable_and_dtype(
        input, 'input/x', ['float16', 'float32', 'float64'], 'softmax'
    )
1309

1310
    dtype = helper.input_dtype()
X
Xin Pan 已提交
1311
    softmax_out = helper.create_variable_for_type_inference(dtype)
1312 1313 1314 1315 1316 1317
    helper.append_op(
        type="softmax",
        inputs={"X": input},
        outputs={"Out": softmax_out},
        attrs=attrs,
    )
1318 1319 1320
    return softmax_out


1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335
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",
):
1336
    r"""
1337 1338
    :api_attr: Static Graph

C
chengduoZH 已提交
1339
    The convolution2D layer calculates the output based on the input, filter
T
tensor-tang 已提交
1340
    and strides, paddings, dilations, groups parameters. Input and
L
liym27 已提交
1341
    Output are in NCHW or NHWC format, where N is batch size, C is the number of
1342
    channels, H is the height of the feature, and W is the width of the feature.
T
tensor-tang 已提交
1343 1344 1345 1346 1347 1348
    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/>`_
1349
    for more details.
1350 1351 1352
    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 已提交
1353

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

C
chengduoZH 已提交
1356 1357
    .. math::

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

T
tensor-tang 已提交
1360
    Where:
C
chengduoZH 已提交
1361

L
liym27 已提交
1362
    * :math:`X`: Input value, a tensor with NCHW or NHWC format.
1363 1364 1365 1366
    * :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 已提交
1367
    * :math:`Out`: Output value, the shape of :math:`Out` and :math:`X` may be different.
C
chengduoZH 已提交
1368 1369 1370

    Example:

1371 1372
        - Input:

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

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

1377
        - Output:
T
tensor-tang 已提交
1378

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

C
chengduoZH 已提交
1381
        Where
1382 1383

        .. math::
C
chengduoZH 已提交
1384

W
weixing02 已提交
1385 1386
            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 已提交
1387 1388

    Args:
1389
        input (Tensor): The input is 4-D Tensor with shape [N, C, H, W], the data type
L
lvmengsi 已提交
1390
            of input is float16 or float32 or float64.
T
tensor-tang 已提交
1391
        num_filters(int): The number of filter. It is as same as the output
1392
            image channel.
1393 1394
        filter_size (int|tuple): The filter size. If filter_size
            is a tuple, it must contain two integers, (filter_size_height,
L
lvmengsi 已提交
1395 1396
            filter_size_width). Otherwise, filter_size_height = filter_size_width =\
            filter_size.
1397 1398
        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 已提交
1399 1400
            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 已提交
1401
            on both sides for each dimension.If `padding` is a string, either 'VALID' or
L
liym27 已提交
1402 1403
            '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
1404 1405
            `[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 已提交
1406
            [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right]]`.
L
liym27 已提交
1407 1408 1409
            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 已提交
1410
        dilation (int|tuple): The dilation size. It means the spacing between the kernel
1411 1412
            points. If dilation is a tuple, it must contain two integers, (dilation_height,
            dilation_width). Otherwise, dilation_height = dilation_width = dilation.
L
lvmengsi 已提交
1413
            Default: dilation = 1.
1414 1415 1416 1417
        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 已提交
1418 1419 1420 1421 1422
            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 已提交
1423
            and the :math:`std` is :math:`(\\frac{2.0 }{filter\_elem\_num})^{0.5}`. Default: None.
C
chengduo 已提交
1424 1425 1426 1427 1428
        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.
1429 1430
        use_cudnn (bool): Use cudnn kernel or not, it is valid only when the cudnn
            library is installed. Default: True
C
chengduo 已提交
1431 1432
        act (str): Activation type, if it is set to None, activation is not appended.
            Default: None
1433 1434
        name(str|None): For detailed information, please refer
           to :ref:`api_guide_Name`. Usually name is no need to set and
L
lvmengsi 已提交
1435
           None by default.
1436
        data_format (str, optional): Specify the data format of the input, and the data format of the output
1437
            will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`.
L
liym27 已提交
1438 1439
            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 已提交
1440 1441

    Returns:
1442 1443 1444
        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 已提交
1445
        and non-linearity activation result.
C
refine  
chengduoZH 已提交
1446

1447 1448 1449 1450 1451
    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".
1452
        ValueError: If `padding` is a tuple, but the element corresponding to the input's batch size is not 0
1453 1454 1455 1456 1457 1458 1459
            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 已提交
1460 1461 1462
    Examples:
        .. code-block:: python

1463 1464
          import paddle
          paddle.enable_static()
1465

1466 1467 1468
          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 已提交
1469 1470
    """

1471 1472 1473
    check_variable_and_dtype(
        input, 'input', ['float16', 'float32', 'float64'], 'conv2d'
    )
1474
    if len(input.shape) != 4:
1475 1476 1477 1478
        raise ValueError(
            "Input size should be 4, "
            "but received {}".format(len(input.shape))
        )
1479
    num_channels = input.shape[1]
L
liym27 已提交
1480
    if not isinstance(use_cudnn, bool):
1481 1482 1483 1484
        raise ValueError(
            "Attr(use_cudnn) should be True or False. Received "
            "Attr(use_cudnn): %s. " % str(use_cudnn)
        )
L
liym27 已提交
1485 1486 1487 1488

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

1492
    channel_last = data_format == "NHWC"
L
liym27 已提交
1493 1494 1495 1496
    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. "
1497 1498
            "Received: %s." % (str(input.shape), str(num_channels))
        )
C
chengduo 已提交
1499
    assert param_attr is not False, "param_attr should not be False here."
L
liym27 已提交
1500

1501 1502 1503
    if groups is None:
        num_filter_channels = num_channels
    elif groups <= 0:
1504 1505
        raise ValueError(
            "the groups of input must be greater than 0, "
1506 1507
            "but received the groups of input is {}".format(groups)
        )
1508 1509 1510 1511 1512
    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 {}"
1513 1514
                ", the groups is {}".format(num_channels, input.shape, groups)
            )
1515 1516
        num_filter_channels = num_channels // groups

1517
    l_type = 'conv2d'
1518 1519 1520 1521 1522
    if (
        num_channels == groups
        and num_filters % num_channels == 0
        and not use_cudnn
    ):
1523
        l_type = 'depthwise_conv2d'
1524

1525 1526 1527 1528 1529
    if (
        num_channels == groups
        and num_filters % num_channels == 0
        and core.is_compiled_with_rocm()
    ):
1530 1531
        l_type = 'depthwise_conv2d'

1532 1533
    # NPU only supports depthwise_conv2d when  "input_channel = output_channel = groups"
    if core.is_compiled_with_npu():
1534
        if num_channels == groups and num_channels == num_filters:
1535 1536 1537 1538
            l_type = 'depthwise_conv2d'
        else:
            l_type = 'conv2d'

1539 1540 1541
    helper = LayerHelper(l_type, **locals())
    dtype = helper.input_dtype()

C
chengduoZH 已提交
1542 1543
    filter_size = utils.convert_to_list(filter_size, 2, 'filter_size')
    stride = utils.convert_to_list(stride, 2, 'stride')
1544
    dilation = utils.convert_to_list(dilation, 2, 'dilation')
C
chengduoZH 已提交
1545

L
liym27 已提交
1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557
    # 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 "
1558 1559
                        "is not supported." % str(padding)
                    )
L
liym27 已提交
1560 1561 1562 1563 1564 1565
                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 "
1566 1567
                        "is not supported." % str(padding)
                    )
L
liym27 已提交
1568 1569 1570
                padding = padding[1:3]
                padding = [ele for a_list in padding for ele in a_list]
            padding = utils.convert_to_list(padding, 4, 'padding')
1571 1572 1573
            if utils._is_symmetric_padding(padding, 2):
                padding = [padding[0], padding[2]]

L
liym27 已提交
1574 1575 1576 1577 1578 1579 1580 1581 1582 1583
        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(
1584 1585 1586
                "Unknown padding: '%s'. It can only be 'SAME' or 'VALID'."
                % str(padding)
            )
L
liym27 已提交
1587 1588
        if padding == "VALID":
            padding_algorithm = "VALID"
1589
            padding = [0, 0]
L
liym27 已提交
1590 1591
        elif padding == "SAME":
            padding_algorithm = "SAME"
1592
            padding = [0, 0]
L
liym27 已提交
1593 1594

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

M
minqiyang 已提交
1596
    filter_shape = [num_filters, int(num_filter_channels)] + filter_size
Y
Yu Yang 已提交
1597 1598

    def _get_default_param_initializer():
C
chengduo 已提交
1599
        filter_elem_num = filter_size[0] * filter_size[1] * num_channels
1600 1601 1602 1603
        if filter_elem_num <= 0:
            raise ValueError(
                "Invalid filter number, excepted number is larger than 0, but"
                " received {}, please check the input shape and "
1604 1605 1606
                "filter size.".format(filter_elem_num)
            )
        std = (2.0 / filter_elem_num) ** 0.5
Y
Yu Yang 已提交
1607 1608 1609 1610 1611 1612
        return Normal(0.0, std, 0)

    filter_param = helper.create_parameter(
        attr=helper.param_attr,
        shape=filter_shape,
        dtype=dtype,
1613 1614
        default_initializer=_get_default_param_initializer(),
    )
Y
Yu Yang 已提交
1615

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

1618 1619 1620 1621 1622 1623
    if (
        core.is_compiled_with_cuda()
        and paddle.fluid.get_flags("FLAGS_conv2d_disable_cudnn")[
            "FLAGS_conv2d_disable_cudnn"
        ]
    ):
1624 1625
        use_cudnn = False

1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644
    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 已提交
1645

1646 1647 1648 1649
    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 已提交
1650 1651 1652 1653

    return helper.append_activation(pre_act)


F
fengjiayi 已提交
1654
@templatedoc()
1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667
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 已提交
1668
    """
1669

F
fengjiayi 已提交
1670
    ${comment}
1671 1672

    Args:
K
Kaipeng Deng 已提交
1673 1674 1675 1676 1677
        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 已提交
1678
        pool_size (int|list|tuple): The pool kernel size. If pool kernel size is a tuple or list,
J
JiabinYang 已提交
1679 1680
            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 已提交
1681
        pool_type: ${pooling_type_comment}
J
JiabinYang 已提交
1682 1683 1684
        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.
1685 1686 1687 1688 1689 1690 1691
        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 已提交
1692
            Otherwise, the pool padding size will be a square of an int.
1693 1694 1695
        global_pooling (bool): ${global_pooling_comment}
        use_cudnn (bool): ${use_cudnn_comment}
        ceil_mode (bool): ${ceil_mode_comment}
K
Kaipeng Deng 已提交
1696 1697 1698
        name(str, optional): For detailed information, please refer
                             to :ref:`api_guide_Name`. Usually name is no need to set and
                             None by default.
1699
        exclusive (bool): Whether to exclude padding points in average pooling
1700
                          mode, default is `true`.
1701
        data_format (string): The data format of the input and output data. An optional string from: `"NCHW"`, `"NHWC"`.
1702 1703
                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 已提交
1704

1705
    Returns:
K
Kaipeng Deng 已提交
1706
        Variable: The output tensor of pooling result. The data type is same as input tensor.
F
fengjiayi 已提交
1707 1708

    Raises:
1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720
        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 已提交
1721 1722 1723 1724 1725

    Examples:

        .. code-block:: python

1726
          import paddle.fluid as fluid
1727 1728 1729
          import paddle

          paddle.enable_static()
1730

K
Kaipeng Deng 已提交
1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755
          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)
1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773

          # 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 已提交
1774 1775 1776
    """
    if pool_type not in ["max", "avg"]:
        raise ValueError(
1777
            "Unknown Attr(pool_type): '%s'. It can only be 'max' or 'avg'.",
1778 1779
            str(pool_type),
        )
C
chengduoZH 已提交
1780

C
chengduoZH 已提交
1781 1782
    if global_pooling is False and pool_size == -1:
        raise ValueError(
1783
            "When Attr(global_pooling) is False, Attr(pool_size) must be passed "
1784 1785
            "and be a valid value. Received pool_size: %s." % str(pool_size)
        )
1786 1787

    if not isinstance(use_cudnn, bool):
1788 1789 1790 1791
        raise TypeError(
            "Attr(use_cudnn) should be True or False. Received "
            "Attr(use_cudnn): %s." % str(use_cudnn)
        )
1792 1793 1794 1795

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

C
chengduoZH 已提交
1799 1800 1801
    pool_size = utils.convert_to_list(pool_size, 2, 'pool_size')
    pool_stride = utils.convert_to_list(pool_stride, 2, 'pool_stride')

1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812
    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 "
1813 1814
                        "is not supported." % str(padding)
                    )
1815 1816 1817 1818 1819 1820
                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 "
1821 1822
                        "is not supported." % str(padding)
                    )
1823 1824 1825
                padding = padding[1:3]
                padding = [ele for a_list in padding for ele in a_list]
            padding = utils.convert_to_list(padding, 4, 'padding')
1826

1827 1828
            if utils._is_symmetric_padding(padding, 2):
                padding = [padding[0], padding[2]]
1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839
        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'."
1840 1841
                % str(pool_padding)
            )
1842 1843
        if pool_padding == "VALID":
            padding_algorithm = "VALID"
1844
            pool_padding = [0, 0]
1845 1846 1847
            if ceil_mode != False:
                raise ValueError(
                    "When Attr(pool_padding) is \"VALID\", Attr(ceil_mode) must be False. "
1848 1849
                    "Received ceil_mode: True."
                )
1850 1851
        elif pool_padding == "SAME":
            padding_algorithm = "SAME"
1852
            pool_padding = [0, 0]
1853 1854

    pool_padding = update_padding(pool_padding, data_format)
1855
    if in_dygraph_mode():
1856
        input = input._use_cudnn(use_cudnn)
1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869
        return _C_ops.pool2d(
            input,
            pool_size,
            pool_stride,
            pool_padding,
            ceil_mode,
            exclusive,
            data_format,
            pool_type,
            global_pooling,
            False,
            padding_algorithm,
        )
1870 1871
    op_type = 'pool2d'
    helper = LayerHelper(op_type, **locals())
Y
Yu Yang 已提交
1872
    dtype = helper.input_dtype()
X
Xin Pan 已提交
1873
    pool_out = helper.create_variable_for_type_inference(dtype)
Y
Yu Yang 已提交
1874

1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892
    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,
        },
    )
1893 1894 1895 1896

    return pool_out


1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912
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,
):
1913
    r"""
1914 1915
    :api_attr: Static Graph

Q
qiaolongfei 已提交
1916 1917
    **Batch Normalization Layer**

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

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

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

Q
qiaolongfei 已提交
1925 1926 1927
    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 已提交
1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939

    :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
1940

L
lvmengsi 已提交
1941
        moving\_mean = moving\_mean * momentum + mini-batch\_mean * (1. - momentum) \\\\
1942
        moving\_var = moving\_var * momentum + mini-batch\_var * (1. - momentum)
L
lvmengsi 已提交
1943

1944

L
lvmengsi 已提交
1945
    moving_mean is global mean and moving_var is global variance.
1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958

    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 已提交
1959
    Note:
1960
        if build_strategy.sync_batch_norm=True, the batch_norm in network will use
L
lvmengsi 已提交
1961
        sync_batch_norm automatically.
1962
        `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 已提交
1963

1964
    Args:
1965
        input(Tensor): The rank of input Tensor can be 2, 3, 4, 5. The data type
L
lvmengsi 已提交
1966
            is float16 or float32 or float64.
Q
qiaolongfei 已提交
1967
        act(string, Default None): Activation type, linear|relu|prelu|...
Q
qingqing01 已提交
1968 1969
        is_test (bool, Default False): A flag indicating whether it is in
            test phrase or not.
1970 1971
        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
1972
            shape [1] and data type as float32. The updated formula is:
Q
qingqing01 已提交
1973 1974 1975 1976 1977
            :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 已提交
1978 1979
        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
1980
	     will create ParamAttr as param_attr, the name of scale can be set in ParamAttr.
1981
	     If the Initializer of the param_attr is not set, the parameter is initialized
1982
	     with Xavier. Default: None.
C
chengduo 已提交
1983 1984
        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
1985 1986
	     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.
1987
	     Default: None.
1988
        data_layout (str, optional): Specify the data format of the input, and the data format of the output
K
Kaipeng Deng 已提交
1989 1990 1991
             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]`.
1992
        in_place(bool, Default False): Make the input and output of batch norm reuse memory.
1993 1994 1995 1996
        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
1997
            will save global mean with the string.
L
lvmengsi 已提交
1998
        moving_variance_name(str, Default None): The name of the moving_variance which store the global Variance.
1999
            If it is set to None, batch_norm will save global variance with a random name, otherwise, batch_norm
2000
            will save global variance with the string.
2001 2002
        do_model_average_for_mean_and_var(bool, Default True): Whether parameter mean and variance should do model
            average when model average is enabled.
2003 2004 2005 2006 2007
        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.
2008
    Returns:
2009
        A Tensor which is the result after applying batch normalization on the input,
2010
        has same shape and data type with input.
Q
qiaolongfei 已提交
2011 2012 2013 2014 2015

    Examples:

        .. code-block:: python

2016
            import paddle
2017

2018
            paddle.enable_static()
2019 2020 2021 2022 2023 2024 2025
            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 已提交
2026
    """
2027 2028 2029
    assert (
        bias_attr is not False
    ), "bias_attr should not be False in batch_norm."
Y
Yu Yang 已提交
2030 2031
    helper = LayerHelper('batch_norm', **locals())

2032 2033 2034
    check_variable_and_dtype(
        input, 'input', ['float16', 'float32', 'float64'], 'batch_norm'
    )
2035
    dtype = helper.input_dtype()
2036

W
Wu Yi 已提交
2037 2038 2039 2040
    # use fp32 for bn parameter
    if dtype == core.VarDesc.VarType.FP16:
        dtype = core.VarDesc.VarType.FP32

Y
Yu Yang 已提交
2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052
    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
2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072
    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,
    )
2073 2074
    mean.stop_gradient = True

2075 2076 2077 2078 2079 2080 2081 2082 2083 2084
    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,
    )
2085
    variance.stop_gradient = True
Y
Yu Yang 已提交
2086 2087 2088 2089

    # create output
    # mean and mean_out share the same memory
    mean_out = mean
2090
    # variance and variance_out share the same memory
Y
Yu Yang 已提交
2091
    variance_out = variance
2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103

    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:
2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119
            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,
            )
2120
        else:
2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134
            attrs_ = (
                'epsilon',
                epsilon,
                'is_test',
                is_test,
                'data_layout',
                data_layout,
                'use_mkldnn',
                False,
                'fuse_with_relu',
                False,
                'use_global_stats',
                use_global_stats,
            )
2135
        if inputs_has_MomemtumTensor:
2136
            batch_norm_out, _, _, _, _, _ = _legacy_C_ops.batch_norm(
2137 2138 2139 2140 2141 2142 2143 2144 2145 2146
                input,
                scale,
                bias,
                mean,
                variance,
                momentum,
                mean_out,
                variance_out,
                *attrs_,
            )
2147
        else:
2148
            batch_norm_out, _, _, _, _, _ = _legacy_C_ops.batch_norm(
2149 2150 2151 2152 2153 2154 2155 2156 2157 2158
                input,
                scale,
                bias,
                mean,
                variance,
                None,
                mean_out,
                variance_out,
                *attrs_,
            )
2159

2160 2161 2162
        return dygraph_utils._append_activation_in_dygraph(
            batch_norm_out, act=act, use_mkldnn=False
        )
2163

2164 2165 2166
    saved_mean = helper.create_variable_for_type_inference(
        dtype=dtype, stop_gradient=True
    )
X
Xin Pan 已提交
2167
    saved_variance = helper.create_variable_for_type_inference(
2168 2169
        dtype=dtype, stop_gradient=True
    )
2170
    reserve_space = None
2171
    if not is_test:
2172
        reserve_space = helper.create_variable_for_type_inference(
2173 2174
            dtype=helper.input_dtype(), stop_gradient=True
        )
2175

2176 2177 2178
    batch_norm_out = (
        input if in_place else helper.create_variable_for_type_inference(dtype)
    )
Y
Yu Yang 已提交
2179

2180 2181 2182 2183 2184
    inputs = {
        "X": input,
        "Scale": scale,
        "Bias": bias,
        "Mean": mean,
2185 2186
        "Variance": variance,
        "MeanOut": mean_out,
2187
        "VarianceOut": variance_out,
2188 2189 2190 2191 2192 2193 2194
    }
    attrs = {
        "epsilon": epsilon,
        "is_test": is_test,
        "data_layout": data_layout,
        "use_mkldnn": False,
        "fuse_with_relu": False,
2195
        "use_global_stats": use_global_stats,
2196 2197 2198 2199 2200
    }
    if isinstance(momentum, Variable):
        inputs['MomemtumTensor'] = momentum
    else:
        attrs['momentum'] = momentum
2201 2202 2203 2204 2205 2206

    outputs = {
        "Y": batch_norm_out,
        "MeanOut": mean_out,
        "VarianceOut": variance_out,
        "SavedMean": saved_mean,
2207
        "SavedVariance": saved_variance,
2208 2209 2210 2211
    }
    if reserve_space is not None:
        outputs["ReserveSpace"] = reserve_space

2212 2213 2214
    helper.append_op(
        type="batch_norm", inputs=inputs, outputs=outputs, attrs=attrs
    )
Y
Yu Yang 已提交
2215 2216 2217 2218

    return helper.append_activation(batch_norm_out)


Y
yuyang18 已提交
2219
@templatedoc()
2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230
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,
):
2231
    r"""
2232 2233
    :api_attr: Static Graph

2234 2235 2236 2237
    **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 已提交
2238 2239 2240

    The formula is as follows:

Y
yuyang18 已提交
2241
    ..  math::
G
guosheng 已提交
2242

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

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

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

2249 2250 2251 2252 2253
    - :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 已提交
2254

G
guosheng 已提交
2255
    Args:
2256
        input(Tensor): A multi-dimension ``Tensor`` , and the data type is float32 or float64.
2257 2258 2259 2260 2261
        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 已提交
2262
            dimensions from :attr:`begin_norm_axis` to :attr:`rank(input)`.
2263 2264 2265 2266
            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 已提交
2267 2268
            gain :math:`g`. If :attr:`scale` is False, :attr:`param_attr` is
            omitted. If :attr:`scale` is True and :attr:`param_attr` is None,
2269
            a default :code:`ParamAttr` would be added as scale. The
2270 2271
            :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 已提交
2272 2273
            bias :math:`b`. If :attr:`shift` is False, :attr:`bias_attr` is
            omitted. If :attr:`shift` is True and :attr:`param_attr` is None,
2274
            a default :code:`ParamAttr` would be added as bias. The
2275
            :attr:`bias_attr` is initialized as 0 if it is added. Default: None.
T
tianshuo78520a 已提交
2276
        act(str, optional): Activation to be applied to the output of layer normalization.
2277 2278
                  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 已提交
2279 2280

    Returns:
2281
        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 已提交
2282 2283 2284

    Examples:

2285 2286
        .. code-block:: python

2287 2288
            import paddle
            paddle.enable_static()
2289 2290 2291
            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 已提交
2292
    """
2293 2294 2295
    assert (
        _non_static_mode() is not True
    ), "please use LayerNorm instead of layer_norm in dygraph mode!"
G
guosheng 已提交
2296
    helper = LayerHelper('layer_norm', **locals())
2297 2298 2299
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'layer_norm'
    )
G
guosheng 已提交
2300 2301 2302 2303 2304 2305 2306
    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:
2307 2308 2309 2310 2311 2312 2313 2314 2315
        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 已提交
2316
        inputs['Scale'] = scale
2317 2318
    else:
        if param_attr:
T
tianshuo78520a 已提交
2319
            warnings.warn("param_attr is only available with scale is True.")
G
guosheng 已提交
2320
    if shift:
2321 2322 2323 2324 2325 2326
        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 已提交
2327
        inputs['Bias'] = bias
2328 2329
    else:
        if bias_attr:
T
tianshuo78520a 已提交
2330
            warnings.warn("bias_attr is only available with shift is True.")
G
guosheng 已提交
2331 2332

    # create output
2333 2334 2335 2336 2337 2338
    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 已提交
2339
    layer_norm_out = helper.create_variable_for_type_inference(dtype)
G
guosheng 已提交
2340

2341 2342 2343 2344 2345 2346 2347 2348 2349 2350
    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 已提交
2351 2352 2353 2354

    return helper.append_activation(layer_norm_out)


D
dengkaipeng 已提交
2355
@templatedoc()
2356
def spectral_norm(weight, dim=0, power_iters=1, eps=1e-12, name=None):
2357
    r"""
2358 2359
    :api_attr: Static Graph

D
dengkaipeng 已提交
2360 2361
    **Spectral Normalization Layer**

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

D
dengkaipeng 已提交
2367 2368 2369
    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 已提交
2370
    and W is the product result of remaining dimensions.
D
dengkaipeng 已提交
2371 2372

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

2377
    .. math::
D
dengkaipeng 已提交
2378 2379 2380 2381 2382 2383

        \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 已提交
2384
    Calculate :math:`\sigma(\mathbf{W})` and normalize weight values.
D
dengkaipeng 已提交
2385 2386 2387 2388

    .. math::

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

D
dengkaipeng 已提交
2390
        \mathbf{W} = \\frac{\mathbf{W}}{\sigma(\mathbf{W})}
2391

2392

D
dengkaipeng 已提交
2393 2394 2395
    Refer to `Spectral Normalization <https://arxiv.org/abs/1802.05957>`_ .

    Args:
C
Chen Long 已提交
2396
        weight(Tensor): ${weight_comment}
D
dengkaipeng 已提交
2397 2398 2399
        dim(int): ${dim_comment}
        power_iters(int): ${power_iters_comment}
        eps(float): ${eps_comment}
K
Kaipeng Deng 已提交
2400 2401 2402
        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 已提交
2403 2404

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

    Examples:
K
Kaipeng Deng 已提交
2409
       .. code-block:: python
D
dengkaipeng 已提交
2410

2411
            import paddle
K
Kaipeng Deng 已提交
2412

2413
            paddle.enable_static()
C
Chen Long 已提交
2414
            weight = paddle.static.data(name='weight', shape=[2, 8, 32, 32], dtype='float32')
2415
            x = paddle.static.nn.spectral_norm(weight=weight, dim=1, power_iters=2)
C
Chen Long 已提交
2416
            print(x.shape) # [2, 8, 32, 32]
D
dengkaipeng 已提交
2417 2418
    """
    helper = LayerHelper('spectral_norm', **locals())
2419 2420 2421
    check_variable_and_dtype(
        weight, 'weight', ['float32', 'float64'], 'spectral_norm'
    )
2422 2423 2424
    check_type(dim, 'dim', int, 'spectral_norm')
    check_type(power_iters, 'power_iters', int, 'spectral_norm')
    check_type(eps, 'eps', float, 'spectral_norm')
2425
    dtype = weight.dtype
D
dengkaipeng 已提交
2426 2427

    # create intput and parameters
2428
    input_shape = weight.shape
2429
    assert weight.numel() > 0, "Any dimension of input cannot be equal to 0."
2430 2431 2432 2433 2434
    assert dim < len(input_shape), (
        "The input `dim` should be less than the "
        "rank of `weight`, but received dim="
        "{}".format(dim)
    )
2435 2436 2437
    h = input_shape[dim]
    w = np.prod(input_shape) // h

2438 2439 2440 2441 2442 2443
    u = helper.create_parameter(
        attr=ParamAttr(),
        shape=[h],
        dtype=dtype,
        default_initializer=Normal(0.0, 1.0),
    )
2444
    u.stop_gradient = True
2445 2446 2447 2448 2449 2450
    v = helper.create_parameter(
        attr=ParamAttr(),
        shape=[w],
        dtype=dtype,
        default_initializer=Normal(0.0, 1.0),
    )
2451
    v.stop_gradient = True
D
dengkaipeng 已提交
2452

2453 2454 2455 2456 2457 2458 2459
    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 已提交
2460
    # create output
2461
    out = helper.create_variable(dtype=dtype)
D
Dun 已提交
2462

2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474
    helper.append_op(
        type="spectral_norm",
        inputs=inputs,
        outputs={
            "Out": out,
        },
        attrs={
            "dim": dim,
            "power_iters": power_iters,
            "eps": eps,
        },
    )
D
Dun 已提交
2475

2476
    return out
D
Dun 已提交
2477 2478


C
caoying03 已提交
2479
def reduce_sum(input, dim=None, keep_dim=False, name=None):
G
guosheng 已提交
2480
    """
2481

Y
yangyaming 已提交
2482
    Computes the sum of tensor elements over the given dimension.
G
guosheng 已提交
2483 2484

    Args:
2485 2486 2487
        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 已提交
2488 2489
            :attr:`None`, sum all elements of :attr:`input` and return a
            Tensor variable with a single element, otherwise must be in the
W
whs 已提交
2490 2491
            range :math:`[-rank(input), rank(input))`. If :math:`dim[i] < 0`,
            the dimension to reduce is :math:`rank + dim[i]`.
2492
        keep_dim (bool, optional): Whether to reserve the reduced dimension in the
Y
yangyaming 已提交
2493
            output Tensor. The result tensor will have one fewer dimension
2494 2495 2496 2497
            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 已提交
2498 2499

    Returns:
2500 2501
        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 已提交
2502

2503 2504
    Raises:
        TypeError, if out data type is different with the input data type.
2505

G
guosheng 已提交
2506 2507 2508
    Examples:
        .. code-block:: python

2509
            import paddle.fluid as fluid
2510 2511
            import paddle
            paddle.enable_static()
G
guosheng 已提交
2512 2513 2514
            # 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 已提交
2515
            # Each example is followed by the corresponding output tensor.
2516
            x = fluid.data(name='x', shape=[2, 4], dtype='float32')
G
guosheng 已提交
2517 2518 2519 2520
            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 已提交
2521

2522
            # y is a Tensor variable with shape [2, 2, 2] and elements as below:
W
whs 已提交
2523 2524
            #      [[[1, 2], [3, 4]],
            #      [[5, 6], [7, 8]]]
Q
qiaolongfei 已提交
2525
            # Each example is followed by the corresponding output tensor.
2526
            y = fluid.data(name='y', shape=[2, 2, 2], dtype='float32')
2527 2528
            fluid.layers.reduce_sum(y, dim=[1, 2]) # [10, 26]
            fluid.layers.reduce_sum(y, dim=[0, 1]) # [16, 20]
W
whs 已提交
2529

G
guosheng 已提交
2530
    """
2531 2532
    reduce_all, dim = _get_reduce_dim(dim, input)

2533
    if in_dygraph_mode():
2534
        return _C_ops.sum(input, dim, None, keep_dim)
2535
    elif _in_legacy_dygraph():
2536 2537 2538
        return _legacy_C_ops.reduce_sum(
            input, 'dim', dim, 'keep_dim', keep_dim, 'reduce_all', reduce_all
        )
2539
    attrs = {'dim': dim, 'keep_dim': keep_dim, 'reduce_all': reduce_all}
2540
    check_variable_and_dtype(
2541 2542 2543 2544 2545
        input,
        'input',
        ['float16', 'float32', 'float64', 'int32', 'int64'],
        'reduce_sum',
    )
2546
    helper = LayerHelper('reduce_sum', **locals())
X
Xin Pan 已提交
2547
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
2548 2549 2550 2551 2552 2553
    helper.append_op(
        type='reduce_sum',
        inputs={'X': input},
        outputs={'Out': out},
        attrs=attrs,
    )
G
guosheng 已提交
2554
    return out
G
guosheng 已提交
2555 2556


2557
@deprecated(since="2.0.0", update_to="paddle.mean")
C
caoying03 已提交
2558
def reduce_mean(input, dim=None, keep_dim=False, name=None):
G
guosheng 已提交
2559
    """
Y
Yibing Liu 已提交
2560
    Computes the mean of the input tensor's elements along the given dimension.
G
guosheng 已提交
2561 2562

    Args:
2563 2564 2565
        input (Variable): The input variable which is a Tensor, the data type is float32,
            float64, int32, int64.
        dim (list|int, optional): The dimension along which the mean is computed. If
Y
Yibing Liu 已提交
2566 2567
            `None`, compute the mean over all elements of :attr:`input`
            and return a variable with a single element, otherwise it
Y
yangyaming 已提交
2568
            must be in the range :math:`[-rank(input), rank(input))`. If
2569
            :math:`dim[i] < 0`, the dimension to reduce is
Y
Yibing Liu 已提交
2570
            :math:`rank(input) + dim[i]`.
2571
        keep_dim (bool, optional): Whether to reserve the reduced dimension in the
Y
yangyaming 已提交
2572
            output Tensor. The result tensor will have one fewer dimension
2573
            than the :attr:`input` unless :attr:`keep_dim` is true, default
2574 2575 2576
            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`
2577

G
guosheng 已提交
2578
    Returns:
2579 2580
        Variable: Tensor, results of average on the specified dim of input tensor,
        it's data type is the same as input's Tensor.
2581

2582 2583
    Raises:
        TypeError, if out data type is different with the input data type.
2584

G
guosheng 已提交
2585 2586 2587
    Examples:
        .. code-block:: python

2588
            import paddle
2589
            import paddle.fluid as fluid
2590 2591
            paddle.enable_static()

G
guosheng 已提交
2592 2593 2594
            # x is a Tensor variable with following elements:
            #    [[0.2, 0.3, 0.5, 0.9]
            #     [0.1, 0.2, 0.6, 0.7]]
T
tianshuo78520a 已提交
2595
            # Each example is followed by the corresponding output tensor.
2596
            x = fluid.data(name='x', shape=[2, 4], dtype='float32')
G
guosheng 已提交
2597 2598 2599
            fluid.layers.reduce_mean(x)  # [0.4375]
            fluid.layers.reduce_mean(x, dim=0)  # [0.15, 0.25, 0.55, 0.8]
            fluid.layers.reduce_mean(x, dim=-1)  # [0.475, 0.4]
2600
            fluid.layers.reduce_mean(x, dim=1, keep_dim=True)  # [[0.475], [0.4]]
W
whs 已提交
2601

2602
            # y is a Tensor variable with shape [2, 2, 2] and elements as below:
W
whs 已提交
2603 2604
            #      [[[1.0, 2.0], [3.0, 4.0]],
            #      [[5.0, 6.0], [7.0, 8.0]]]
T
tianshuo78520a 已提交
2605
            # Each example is followed by the corresponding output tensor.
2606
            y = fluid.data(name='y', shape=[2, 2, 2], dtype='float32')
2607 2608
            fluid.layers.reduce_mean(y, dim=[1, 2]) # [2.5, 6.5]
            fluid.layers.reduce_mean(y, dim=[0, 1]) # [4.0, 5.0]
G
guosheng 已提交
2609
    """
2610

2611
    return paddle.mean(x=input, axis=dim, keepdim=keep_dim, name=name)
2612 2613


Z
zhoukunsheng 已提交
2614 2615
def reduce_all(input, dim=None, keep_dim=False, name=None):
    """
2616

2617
    This OP computes the ``logical and`` of tensor elements over the given dimension, and output the result.
Z
zhoukunsheng 已提交
2618 2619

    Args:
2620
        input (Tensor): the input tensor, it's data type should be `bool`.
2621
        dim (list|int|optional): The dimension along which the logical and is computed.
Z
zhoukunsheng 已提交
2622 2623 2624
            If :attr:`None`, compute the logical and over all elements of
            :attr:`input` and return a Tensor variable with a single element,
            otherwise must be in the range :math:`[-rank(input), rank(input))`.
2625
            If :math:`dim[i] < 0`, the dimension to reduce is :math:`rank + dim[i]`. The default value is None.
Z
zhoukunsheng 已提交
2626 2627
        keep_dim (bool): Whether to reserve the reduced dimension in the
            output Tensor. The result tensor will have one fewer dimension
2628
            than the :attr:`input` unless :attr:`keep_dim` is true. The default value is False.
Z
zhoukunsheng 已提交
2629
        name(str|None): A name for this layer(optional). If set None, the layer
2630
                       will be named automatically. The default value is None.
Z
zhoukunsheng 已提交
2631

2632
    Returns:
2633
        Tensor, the output data type is bool. : The reduced tensor variable with ``logical and`` in given dims.
Z
zhoukunsheng 已提交
2634 2635 2636

    Examples:
        .. code-block:: python
2637

2638
            import paddle
2639
            import paddle.fluid as fluid
2640 2641 2642
            import paddle.fluid.layers as layers
            import numpy as np

Z
zhoukunsheng 已提交
2643 2644 2645
            # x is a bool Tensor variable with following elements:
            #    [[True, False]
            #     [True, True]]
2646 2647
            x = fluid.layers.assign(np.array([[1, 0], [1, 1]], dtype='int32'))
            x = fluid.layers.cast(x, 'bool')
2648

2649 2650 2651
            out = fluid.layers.reduce_all(x)  # False
            out = fluid.layers.reduce_all(x, dim=0)  # [True, False]
            out = fluid.layers.reduce_all(x, dim=-1)  # [False, True]
2652 2653
            # keep_dim=False, x.shape=(2,2), out.shape=(2,)

2654
            out = fluid.layers.reduce_all(x, dim=1, keep_dim=True)  # [[False], [True]]
2655
            # keep_dim=True, x.shape=(2,2), out.shape=(2,1)
Z
zhoukunsheng 已提交
2656 2657

    """
2658 2659
    if dim is not None and not isinstance(dim, list):
        dim = [dim]
2660 2661

    if in_dygraph_mode():
2662
        return _C_ops.all(input, dim if dim is not None else [], keep_dim)
2663

2664
    check_variable_and_dtype(input, 'input', ('bool'), 'reduce_all')
Z
zhoukunsheng 已提交
2665 2666
    helper = LayerHelper('reduce_all', **locals())
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
2667 2668 2669 2670 2671
    helper.append_op(
        type='reduce_all',
        inputs={'X': input},
        outputs={'Out': out},
        attrs={
2672
            'dim': dim if dim is not None and dim != [] else [0],
2673 2674
            'keep_dim': keep_dim,
            'reduce_all': True
2675
            if dim is None or dim == [] or len(dim) == len(input.shape)
2676 2677 2678
            else False,
        },
    )
Z
zhoukunsheng 已提交
2679 2680 2681 2682 2683
    return out


def reduce_any(input, dim=None, keep_dim=False, name=None):
    """
2684
    This OP computes the ``logical or`` of tensor elements over the given dimension, and output the result.
Z
zhoukunsheng 已提交
2685 2686

    Args:
2687
        input (Tensor): the input tensor, it's data type should be `bool`.
2688 2689
        dim (list|int|optional): The dimension along which the logical and is computed.
            If :attr:`None`, compute the logical and over all elements of
Z
zhoukunsheng 已提交
2690 2691
            :attr:`input` and return a Tensor variable with a single element,
            otherwise must be in the range :math:`[-rank(input), rank(input))`.
2692
            If :math:`dim[i] < 0`, the dimension to reduce is :math:`rank + dim[i]`. The default value is None.
Z
zhoukunsheng 已提交
2693 2694
        keep_dim (bool): Whether to reserve the reduced dimension in the
            output Tensor. The result tensor will have one fewer dimension
2695
            than the :attr:`input` unless :attr:`keep_dim` is true. The default value is False.
2696
        name (str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.
Z
zhoukunsheng 已提交
2697

2698
    Returns:
2699
        Tensor, the output data type is bool. : The reduced tensor variable with ``logical or`` in given dims.
Z
zhoukunsheng 已提交
2700 2701 2702

    Examples:
        .. code-block:: python
Z
zhoukunsheng 已提交
2703

2704
            import paddle
2705
            import paddle.fluid as fluid
2706 2707 2708
            import paddle.fluid.layers as layers
            import numpy as np

Z
zhoukunsheng 已提交
2709 2710 2711
            # x is a bool Tensor variable with following elements:
            #    [[True, False]
            #     [False, False]]
2712 2713
            x = fluid.layers.assign(np.array([[1, 0], [0, 0]], dtype='int32'))
            x = fluid.layers.cast(x, 'bool')
2714

2715 2716 2717
            out = fluid.layers.reduce_any(x)  # True
            out = fluid.layers.reduce_any(x, dim=0)  # [True, False]
            out = fluid.layers.reduce_any(x, dim=-1)  # [True, False]
2718 2719
            # keep_dim=False, x.shape=(2,2), out.shape=(2,)

2720
            out = fluid.layers.reduce_any(x, dim=1,
Z
zhoukunsheng 已提交
2721
                                     keep_dim=True)  # [[True], [False]]
2722
            # keep_dim=True, x.shape=(2,2), out.shape=(2,1)
Z
zhoukunsheng 已提交
2723 2724

    """
2725
    check_variable_and_dtype(input, 'input', ('bool'), 'reduce_any')
Z
zhoukunsheng 已提交
2726 2727 2728 2729
    helper = LayerHelper('reduce_any', **locals())
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
    if dim is not None and not isinstance(dim, list):
        dim = [dim]
2730 2731 2732 2733 2734
    helper.append_op(
        type='reduce_any',
        inputs={'X': input},
        outputs={'Out': out},
        attrs={
2735
            'dim': dim if dim is not None and dim != [] else [0],
2736 2737
            'keep_dim': keep_dim,
            'reduce_all': True
2738
            if dim is None or dim == [] or len(dim) == len(input.shape)
2739 2740 2741
            else False,
        },
    )
2742 2743 2744
    return out


C
caoying03 已提交
2745
def split(input, num_or_sections, dim=-1, name=None):
G
guosheng 已提交
2746
    """
2747
    Split the input tensor into multiple sub-Tensors.
G
guosheng 已提交
2748 2749

    Args:
2750
        input (Tensor): A N-D Tensor. The data type is bool, float16, float32, float64, int32 or int64.
2751
        num_or_sections (int|list|tuple): If ``num_or_sections`` is int, then the ``num_or_sections``
2752
            indicates the number of equal sized sub-Tensors that the ``input``
2753
            will be divided into. If ``num_or_sections`` is a list or tuple, the length of it
2754 2755 2756 2757 2758
            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.
2759
        name (str, optional): The default value is None.  Normally there is no need for user to set this property.
2760
            For more information, please refer to :ref:`api_guide_Name` .
G
guosheng 已提交
2761 2762

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

2765
    Example:
G
guosheng 已提交
2766 2767
        .. code-block:: python

2768 2769
            import paddle.fluid as fluid

2770
            # input is a Tensor which shape is [3, 9, 5]
2771
            input = fluid.data(
2772 2773
                 name="input", shape=[3, 9, 5], dtype="float32")

2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787
            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]
2788

2789 2790 2791 2792 2793 2794
            # 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]
2795

G
guosheng 已提交
2796
    """
J
Jiabin Yang 已提交
2797
    if _non_static_mode():
2798 2799 2800
        num = None
        attrs = ()

S
songyouwei 已提交
2801 2802
        if isinstance(dim, Variable):
            dim = dim.numpy()
2803
            dim = dim.item(0)
W
wangzhen38 已提交
2804
        assert len(input.shape) + dim >= 0, "(rank(x) + axis) must >= 0"
S
songyouwei 已提交
2805
        dim = (len(input.shape) + dim) if dim < 0 else dim
2806
        attrs += ('axis', dim)
2807 2808 2809

        if isinstance(num_or_sections, int):
            num = num_or_sections
2810
            attrs += ('num', num_or_sections)
L
Leo Chen 已提交
2811
        elif isinstance(num_or_sections, (list, tuple)):
2812
            num = len(num_or_sections)
L
Leo Chen 已提交
2813
            if utils._contain_var(num_or_sections):
2814 2815
                for index, item in enumerate(num_or_sections):
                    if isinstance(item, Variable):
2816 2817 2818
                        num_or_sections[index] = num_or_sections[index].numpy()[
                            0
                        ]
2819
                attrs += ('sections', list(num_or_sections))
L
Leo Chen 已提交
2820
            else:
2821
                attrs += ('sections', list(num_or_sections))
2822 2823
        else:
            raise TypeError(
2824
                "The type of 'num_or_sections' in split must be int, list or tuple in imperative mode, but "
2825 2826
                "received %s." % (type(num_or_sections))
            )
2827
        if in_dygraph_mode():
C
Charles-hit 已提交
2828 2829 2830 2831
            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)
2832 2833
        elif _in_legacy_dygraph():
            out = [_varbase_creator() for n in range(num)]
2834
            _legacy_C_ops.split(input, out, *attrs)
2835
            return out
L
Leo Chen 已提交
2836

2837
    check_variable_and_dtype(
2838 2839 2840 2841 2842
        input,
        'input',
        ['bool', 'float16', 'float32', 'float64', 'int32', 'int64'],
        'split',
    )
2843 2844 2845 2846
    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')
2847

G
guosheng 已提交
2848
    helper = LayerHelper('split', **locals())
2849

G
guosheng 已提交
2850
    input_shape = input.shape
2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861
    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:
2862
                assert isinstance(dim_size, int)
2863 2864 2865
                if dim_size == -1:
                    assert unk_dim_idx == -1, (
                        "Only one value of 'num_or_section' in split can "
2866 2867 2868
                        "be -1. But received num_or_section[%d] is also -1."
                        % idx
                    )
2869 2870
                    unk_dim_idx = idx
                temp_out = helper.create_variable_for_type_inference('int32')
2871 2872 2873
                fill_constant(
                    [1], 'int32', dim_size, force_cpu=True, out=temp_out
                )
2874 2875 2876 2877 2878 2879 2880
                tensor_list.append(temp_out)
        return tensor_list

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

G
guosheng 已提交
2885 2886
    if isinstance(num_or_sections, int):
        assert num_or_sections > 1, 'num_or_sections must be more than 1.'
2887
        if isinstance(dim, int) and input_shape[dim] > 0:
2888 2889 2890 2891 2892 2893
            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 已提交
2894 2895
        num = num_or_sections
    else:
2896
        if isinstance(dim, int) and input_shape[dim] > 0:
2897 2898 2899
            assert (
                len(num_or_sections) <= input_shape[dim]
            ), 'len(num_or_sections) must not be more than input.shape[dim].'
G
guosheng 已提交
2900
        num = len(num_or_sections)
2901
        attrs['sections'] = list(
2902 2903 2904 2905 2906
            map(
                lambda ele: -1 if isinstance(ele, Variable) else ele,
                num_or_sections,
            )
        )
L
Leo Chen 已提交
2907
        if utils._contain_var(num_or_sections):
2908
            inputs['SectionsTensorList'] = _get_SectionsTensorList(
2909 2910
                num_or_sections
            )
2911

G
guosheng 已提交
2912
    outs = [
X
Xin Pan 已提交
2913
        helper.create_variable_for_type_inference(dtype=helper.input_dtype())
G
guosheng 已提交
2914 2915
        for i in range(num)
    ]
2916 2917 2918
    helper.append_op(
        type='split', inputs=inputs, outputs={'Out': outs}, attrs=attrs
    )
G
guosheng 已提交
2919
    return outs
C
caoying03 已提交
2920 2921 2922


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

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

2928
    .. math::
2929 2930

        y = \\frac{x}{ \sqrt{\sum {x^2} + epsion }}
C
caoying03 已提交
2931 2932 2933 2934 2935

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

    Args:
2936
        x(Variable|list): The input tensor could be N-D tensor, and the input data type could be float16, float32 or float64.
2937
        axis(int): The axis on which to apply normalization. If `axis < 0`, \
2938 2939
            the dimension to normalization is rank(X) + axis. -1 is the
            last dimension.
2940
        epsilon(float): The epsilon value is used to avoid division by zero, \
翟飞跃 已提交
2941
            the default value is 1e-12.
2942
    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`
2943

C
caoying03 已提交
2944
    Returns:
R
ruri 已提交
2945
        Variable: The output has the same shape and data type with `x`.
C
caoying03 已提交
2946 2947

    Examples:
2948

2949 2950
    .. code-block:: python
        :name: code-example1
2951

2952
        import paddle
2953

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

2958 2959 2960
        # [[ 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]]
2961

C
caoying03 已提交
2962
    """
F
fengjiayi 已提交
2963 2964
    if len(x.shape) == 1:
        axis = 0
J
Jiabin Yang 已提交
2965
    if _non_static_mode():
2966 2967 2968
        if in_dygraph_mode():
            out, _ = _C_ops.norm(x, 1 if axis is None else axis, epsilon, False)
        elif _in_legacy_dygraph():
2969 2970 2971
            _, out = _legacy_C_ops.norm(
                x, 'axis', 1 if axis is None else axis, 'epsilon', epsilon
            )
2972 2973 2974
        return out

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

2976
    helper = LayerHelper("l2_normalize", **locals())
X
Xin Pan 已提交
2977 2978
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
    norm = helper.create_variable_for_type_inference(dtype=x.dtype)
2979 2980 2981 2982 2983 2984 2985 2986 2987
    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 已提交
2988
    return out
2989 2990


S
ShenLiang 已提交
2991
@deprecated(since="2.0.0", update_to="paddle.matmul")
S
sneaxiy 已提交
2992
def matmul(x, y, transpose_x=False, transpose_y=False, alpha=1.0, name=None):
G
guosheng 已提交
2993
    """
Y
ying 已提交
2994 2995 2996 2997
    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 已提交
2998

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

3002 3003 3004 3005 3006
    - 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
3007
      :math:`[1, D]` in transposed form.
G
guosheng 已提交
3008

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

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

Y
ying 已提交
3017 3018
    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 已提交
3019
    removed after matrix multiplication.
G
guosheng 已提交
3020 3021 3022

    Args:
        x (Variable): The input variable which is a Tensor or LoDTensor.
3023 3024 3025
        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 已提交
3026
        alpha (float): The scale of output. Default 1.0.
3027
        name(str|None): A name for this layer(optional). If set None, the layer
3028
            will be named automatically.
G
guosheng 已提交
3029 3030

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

G
guosheng 已提交
3033 3034 3035
    Examples:
        .. code-block:: python

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

3040
            # x: [B, M, K], y: [B, K, N]
3041
            # fluid.layers.matmul(x, y)  # out: [B, M, N]
Y
ying 已提交
3042

3043
            # x: [B, M, K], y: [K, N]
3044
            # fluid.layers.matmul(x, y)  # out: [B, M, N]
Y
ying 已提交
3045

3046
            # x: [M, K], y: [K, N]
3047
            # fluid.layers.matmul(x, y)  # out: [M, N]
Y
ying 已提交
3048 3049

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

3052
            # x: [K], y: [K]
3053
            # fluid.layers.matmul(x, y)  # out: [1]
3054

Y
ying 已提交
3055
            # x: [M], y: [N]
3056 3057
            # fluid.layers.matmul(x, y, True, True)  # out: [M, N]

3058
            import paddle
3059
            import paddle.fluid as fluid
3060 3061
            paddle.enable_static()

3062 3063 3064
            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 已提交
3065
    """
J
Jiabin Yang 已提交
3066
    if _non_static_mode():
S
ShenLiang 已提交
3067
        out = _varbase_creator(dtype=x.dtype)
3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078
        _legacy_C_ops.matmul(
            x,
            y,
            out,
            'transpose_X',
            transpose_x,
            'transpose_Y',
            transpose_y,
            'alpha',
            float(alpha),
        )
S
ShenLiang 已提交
3079 3080 3081 3082 3083
        return out

    def __check_input(x, y):
        var_names = {'x': x, 'y': y}
        for name, val in var_names.items():
3084 3085 3086
            check_variable_and_dtype(
                val, name, ['float16', 'float32', 'float64'], 'matmul'
            )
S
ShenLiang 已提交
3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099
        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]:
3100 3101 3102 3103 3104 3105
            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 已提交
3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116

        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, "
3117 3118
                        "Y's shape: %s.\n" % (i, i, x_shape, y_shape)
                    )
S
ShenLiang 已提交
3119

W
wanghuancoder 已提交
3120 3121 3122 3123 3124 3125
    attrs = {
        'transpose_X': transpose_x,
        'transpose_Y': transpose_y,
        'alpha': float(alpha),
    }

S
ShenLiang 已提交
3126 3127 3128 3129
    __check_input(x, y)

    helper = LayerHelper('matmul', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
3130 3131 3132 3133 3134 3135
    helper.append_op(
        type='matmul',
        inputs={'X': x, 'Y': y},
        outputs={'Out': out},
        attrs=attrs,
    )
S
ShenLiang 已提交
3136
    return out
3137 3138


3139
def topk(input, k, name=None):
Q
qingqing01 已提交
3140
    """
3141
    :alias_main: paddle.topk
3142 3143
        :alias: paddle.topk,paddle.tensor.topk,paddle.tensor.search.topk
        :old_api: paddle.fluid.layers.topk
3144

3145
    This OP is used to find values and indices of the k largest entries
Q
qingqing01 已提交
3146 3147
    for the last dimension.

3148 3149
    If the input is a 1-D Tensor, finds the k largest entries and outputs
    their values and indices.
Q
qingqing01 已提交
3150 3151 3152 3153

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

F
fengjiayi 已提交
3154 3155
    .. code-block:: text

3156 3157 3158 3159 3160
        Case 1:

          Input:
            input.shape = [3, 4]
            input.data = [[5, 4, 2, 3],
F
fengjiayi 已提交
3161 3162 3163 3164
                     [9, 7, 10, 25],
                     [6, 2, 10, 1]]
            k = 2

3165
          Output:
F
fengjiayi 已提交
3166
            The first output:
3167 3168
            values.shape = [3, 2]
            values.data = [[5, 4],
F
fengjiayi 已提交
3169 3170 3171 3172
                      [10, 25],
                      [6, 10]]

            The second output:
3173 3174
            indices.shape = [3, 2]
            indices.data = [[0, 1],
F
fengjiayi 已提交
3175 3176 3177
                       [2, 3],
                       [0, 2]]

Q
qingqing01 已提交
3178
    Args:
3179 3180 3181 3182
        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 已提交
3183 3184

    Returns:
3185 3186
        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 已提交
3187

F
fengjiayi 已提交
3188
    Raises:
3189
        ValueError: If :math:`k < 1` or :math:`k > last dimension of input`.
Q
qingqing01 已提交
3190 3191 3192 3193

    Examples:
        .. code-block:: python

3194
            import paddle.fluid as fluid
3195
            import paddle.fluid.layers as layers
3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208
            # 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 已提交
3209
    """
J
Jiabin Yang 已提交
3210
    if _non_static_mode():
3211
        _k = k.numpy().item(0) if isinstance(k, Variable) else k
3212
        out, indices = _legacy_C_ops.top_k(input, 'k', _k)
3213 3214 3215
        out.stop_gradient = True
        indices.stop_gradient = True
        return out, indices
3216

3217 3218
    inputs = {"X": [input]}
    attrs = {}
S
songyouwei 已提交
3219 3220 3221 3222 3223
    if isinstance(k, Variable):
        inputs['K'] = [k]
    else:
        attrs = {'k': k}

3224 3225 3226 3227
    helper = LayerHelper("top_k", **locals())
    values = helper.create_variable_for_type_inference(dtype=input.dtype)
    indices = helper.create_variable_for_type_inference(dtype="int64")

3228 3229 3230 3231 3232 3233
    helper.append_op(
        type="top_k",
        inputs=inputs,
        outputs={"Out": [values], "Indices": [indices]},
        attrs=attrs,
    )
Q
qingqing01 已提交
3234 3235 3236 3237 3238
    values.stop_gradient = True
    indices.stop_gradient = True
    return values, indices


3239 3240 3241
def ctc_greedy_decoder(
    input, blank, input_length=None, padding_value=0, name=None
):
3242
    r"""
S
SunGaofeng 已提交
3243
    This op is used to decode sequences by greedy policy by the following steps:
Y
yi.wu 已提交
3244

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

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

3254 3255 3256 3257 3258
    A simple example as below:

    .. code-block:: text

        Given:
S
SunGaofeng 已提交
3259
        (1) for lod mode:
3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270

        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]]

3271
        input.lod = [[4, 4]]
M
minqiyang 已提交
3272

W
whs 已提交
3273
        Computation:
3274

W
whs 已提交
3275 3276 3277 3278 3279 3280
        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:
3281 3282 3283 3284 3285

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

3286
        output.lod = [[2, 1]]
3287

S
SunGaofeng 已提交
3288
        (2) for padding mode:
3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304

         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]
3305
        step2: Change the argmax result to use padding mode, then argmax result is
3306 3307 3308 3309 3310 3311 3312 3313 3314
                [[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 已提交
3315
    Parameters:
3316

3317 3318
        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 已提交
3319
                         where Lp is the sum of all input sequences' length and
3320 3321
                         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 已提交
3322
                         (not including the blank label). The data type can be float32 or float64.
Y
ying 已提交
3323
        blank(int): the blank label index of Connectionist Temporal
S
SunGaofeng 已提交
3324
                    Classification (CTC) loss, which is in the half-opened
Y
ying 已提交
3325
                    interval [0, num_classes + 1).
S
SunGaofeng 已提交
3326 3327
        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.
3328
        padding_value(int): padding value.
3329 3330 3331
        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`
3332 3333

    Returns:
S
SunGaofeng 已提交
3334 3335 3336 3337 3338
        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 [[]].

3339
        For padding mode, returns a tuple of (output, output_length), which was described as below:
S
SunGaofeng 已提交
3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350

        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).

3351 3352 3353 3354

    Examples:
        .. code-block:: python

3355
            # for lod mode
S
SunGaofeng 已提交
3356
            import paddle.fluid as fluid
S
SunGaofeng 已提交
3357
            x = fluid.data(name='x', shape=[None, 8], dtype='float32', lod_level=1)
3358
            cost = fluid.layers.ctc_greedy_decoder(input=x, blank=0)
3359 3360

            # for padding mode
S
SunGaofeng 已提交
3361 3362
            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')
3363 3364 3365
            out, out_len = fluid.layers.ctc_greedy_decoder(input=x_pad, blank=0,
                            input_length=x_pad_len)

W
wanghaoshuang 已提交
3366
    """
3367 3368 3369
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'ctc_greedy_decoder'
    )
3370

3371
    helper = LayerHelper("ctc_greedy_decoder", **locals())
Q
qingqing01 已提交
3372
    _, topk_indices = topk(input, k=1)
3373 3374

    # ctc align op
X
Xin Pan 已提交
3375
    ctc_out = helper.create_variable_for_type_inference(dtype="int64")
3376 3377

    if input_length is None:
3378 3379 3380 3381 3382 3383
        helper.append_op(
            type="ctc_align",
            inputs={"Input": [topk_indices]},
            outputs={"Output": [ctc_out]},
            attrs={"merge_repeated": True, "blank": blank},
        )
3384 3385 3386
        return ctc_out
    else:
        ctc_out_len = helper.create_variable_for_type_inference(dtype="int64")
3387
        ctc_input = paddle.squeeze(topk_indices, [2])
3388

3389 3390 3391 3392 3393 3394 3395 3396 3397 3398
        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,
            },
        )
3399
        return ctc_out, ctc_out_len
3400 3401


3402 3403 3404 3405 3406 3407 3408 3409 3410
def im2sequence(
    input,
    filter_size=1,
    stride=1,
    padding=0,
    input_image_size=None,
    out_stride=1,
    name=None,
):
3411
    r"""
3412 3413
    :api_attr: Static Graph

3414
    Extracts image patches from the input tensor to form a tensor of shape
L
Liufang Sang 已提交
3415 3416 3417
    {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
3418 3419
    output_height * output_width for an image, in which output_height and
    output_width are calculated by below equation:
3420 3421 3422

    .. math::

L
Liufang Sang 已提交
3423 3424 3425 3426
        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
3427

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

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

L
Liufang Sang 已提交
3433 3434 3435
        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.
3436

L
Liufang Sang 已提交
3437 3438
        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.
3439

L
Liufang Sang 已提交
3440 3441 3442 3443 3444
        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
3445
            padding_up = padding_down = padding_left = padding_right = padding.
L
Liufang Sang 已提交
3446
            Default is 0.
3447

L
Liufang Sang 已提交
3448 3449 3450 3451
        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 已提交
3452
            If out_stride is List,  it must contain two integers,
L
Liufang Sang 已提交
3453 3454 3455 3456 3457
            :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` .
3458 3459 3460

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

    Return Type: Variable
3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490

    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 已提交
3491 3492 3493
            filter = [2, 2]
            stride = [1, 1]
            padding = [0, 0]
3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505

            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.]]

3506
            output.dims = {8, 8}
3507

3508
            output.lod = [[4, 4]]
3509

T
Tink_Y 已提交
3510
    Examples:
3511 3512 3513

        .. code-block:: python

B
Bai Yifan 已提交
3514
            import paddle.fluid as fluid
3515 3516
            import paddle
            paddle.enable_static()
L
Liufang Sang 已提交
3517
            data = fluid.data(name='data', shape=[None, 3, 32, 32],
B
Bai Yifan 已提交
3518
                                     dtype='float32')
3519
            output = fluid.layers.im2sequence(
B
Bai Yifan 已提交
3520 3521
                input=data, stride=[1, 1], filter_size=[2, 2])

3522 3523

    """
3524 3525 3526
    assert (
        not _non_static_mode()
    ), "sequence layer is not supported in dygraph mode yet."
W
wanghaoshuang 已提交
3527

3528 3529
    check_variable_and_dtype(input, 'input', ['float32'], 'im2sequence')

W
wanghaoshuang 已提交
3530 3531 3532 3533 3534 3535 3536 3537 3538
    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])
3539
    inputs = {"X": input}
3540
    attrs = {"kernels": filter_size, "strides": stride, "paddings": padding}
3541 3542 3543 3544 3545
    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
3546
    helper = LayerHelper('im2sequence', **locals())
X
Xin Pan 已提交
3547
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
3548 3549 3550
    helper.append_op(
        type='im2sequence', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
3551
    return out
3552 3553


Y
yuyang18 已提交
3554
@templatedoc()
3555
def row_conv(input, future_context_size, param_attr=None, act=None):
Y
yuyang18 已提交
3556
    """
3557 3558
    :api_attr: Static Graph

Y
yuyang18 已提交
3559
    ${comment}
3560 3561

    Args:
Y
yuyang18 已提交
3562
        input (${x_type}): ${x_comment}.
Y
yangyaming 已提交
3563 3564
        future_context_size (int): Future context size. Please note, the shape
            of convolution kernel is [future_context_size + 1, D].
3565 3566 3567 3568 3569
        param_attr (ParamAttr): Attributes of parameters, including
            name, initializer etc.
        act (str): Non-linear activation to be applied to output variable.

    Returns:
Y
yuyang18 已提交
3570
        ${out_comment}.
3571 3572

    Examples:
B
Bai Yifan 已提交
3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584

      .. 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)
3585 3586
    """
    helper = LayerHelper('row_conv', **locals())
3587
    check_variable_and_dtype(input, 'input', ['float32'], 'row_conv')
3588
    dtype = helper.input_dtype()
3589
    filter_shape = [future_context_size + 1, input.shape[-1]]
3590 3591 3592
    filter_param = helper.create_parameter(
        attr=helper.param_attr, shape=filter_shape, dtype=dtype
    )
X
Xin Pan 已提交
3593
    out = helper.create_variable_for_type_inference(dtype)
3594 3595 3596 3597 3598
    helper.append_op(
        type='row_conv',
        inputs={'X': [input], 'Filter': [filter_param]},
        outputs={'Out': [out]},
    )
Y
yangyaming 已提交
3599
    return helper.append_activation(out)
3600 3601


Y
yuyang18 已提交
3602
@templatedoc()
3603
def multiplex(inputs, index, name=None):
3604
    """
Y
yuyang18 已提交
3605

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

3608
    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 已提交
3609

3610
    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 已提交
3611

3612
    For Example:
L
lujun 已提交
3613

3614
            .. code-block:: text
L
lujun 已提交
3615

3616
                Given:
L
lujun 已提交
3617

3618 3619 3620 3621
                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 已提交
3622

3623
                index = [[3],[0],[1],[2]]
L
lujun 已提交
3624

3625 3626 3627 3628
                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 已提交
3629 3630


3631
    Args:
3632 3633 3634 3635 3636
        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`.
3637
    Returns:
3638
        Tensor: Output of multiplex OP, with data type being float32, float64, int32, int64.
X
xuezhong 已提交
3639 3640

    Examples:
3641

X
xuezhong 已提交
3642 3643
        .. code-block:: python

3644
            import paddle
3645 3646 3647
            import numpy as np
            img1 = np.array([[1, 2], [3, 4]]).astype(np.float32)
            img2 = np.array([[5, 6], [7, 8]]).astype(np.float32)
3648 3649 3650
            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)
3651
            print(res) # [array([[5., 6.], [3., 4.]], dtype=float32)]
X
xuezhong 已提交
3652

3653
    """
3654 3655

    if _in_legacy_dygraph():
3656
        return _legacy_C_ops.multiplex(index, inputs)
3657
    if in_dygraph_mode():
3658
        return _C_ops.multiplex(inputs, index)
3659 3660
    helper = LayerHelper('multiplex', **locals())

3661 3662 3663
    check_type(inputs, 'inputs', (list), 'multiplex')
    if len(inputs) < 2:
        raise ValueError(
3664 3665
            "inputs should be a list object with at least 2 elements."
        )
3666
    for id, x in enumerate(inputs):
3667 3668 3669 3670 3671 3672
        check_variable_and_dtype(
            x,
            'input[' + str(id) + ']',
            ['float32', 'float64', 'int32', 'int64'],
            'multiplex',
        )
3673
    check_variable_and_dtype(index, "index", ['int32', 'int64'], 'multiplex')
3674 3675

    out = helper.create_variable_for_type_inference(inputs[0].dtype)
3676 3677 3678 3679 3680
    helper.append_op(
        type='multiplex',
        inputs={'X': inputs, 'Ids': index},
        outputs={'Out': [out]},
    )
3681
    return out
X
xuezhong 已提交
3682 3683


3684 3685
def smooth_l1(x, y, inside_weight=None, outside_weight=None, sigma=None):
    """
3686

Y
Yibing Liu 已提交
3687 3688
    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 已提交
3689
    For each instance, it computes the smooth L1 loss element by element first
T
tianshuo78520a 已提交
3690
    and then sums all the losses. So the shape of output Variable is
3691
    [batch_size, 1].
3692

3693 3694
    Args:
        x (Variable): A tensor with rank at least 2. The input value of smooth
Q
qingqing01 已提交
3695
            L1 loss op with shape [batch_size, dim1, ..., dimN].
3696
            A LoDTensor or Tensor with type float32.
3697
        y (Variable): A tensor with rank at least 2. The target value of smooth
Y
Yibing Liu 已提交
3698
            L1 loss op with same shape as :attr:`x`.
3699
            A LoDTensor or Tensor with type float32.
3700
        inside_weight (Variable|None):  A tensor with rank at least 2. This
3701 3702
            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 已提交
3703
            by this tensor element by element.
3704
            A Tensor with type float32.
3705
        outside_weight (Variable|None): A tensor with rank at least 2. This
3706 3707
            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 已提交
3708
            element by element.
3709
            A Tensor with type float32.
3710
        sigma (float|None): Hyper parameter of smooth L1 loss layer. A float
3711 3712
           scalar with default value 1.0.

3713
    Returns:
3714
        Variable: The output smooth L1 loss with shape [batch_size, 1].  A Tensor with type float32.
3715 3716 3717 3718

    Examples:
        .. code-block:: python

3719
            import paddle.fluid as fluid
3720
            import numpy as np
3721 3722
            import paddle
            paddle.enable_static()
3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733
            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)
3734

3735 3736 3737 3738
            #[array([[0.08220536],
            #       [0.36652038],
            #      [0.20541131]], dtype=float32)]

3739
    """
3740 3741
    check_variable_and_dtype(x, 'X', ['float32', 'float64'], 'smooth_l1_loss')
    check_variable_and_dtype(y, 'Y', ['float32', 'float64'], 'smooth_l1_loss')
3742

3743
    helper = LayerHelper('smooth_l1_loss', **locals())
3744

X
Xin Pan 已提交
3745 3746
    diff = helper.create_variable_for_type_inference(dtype=x.dtype)
    loss = helper.create_variable_for_type_inference(dtype=x.dtype)
3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757
    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},
    )
3758
    return loss
3759 3760


3761
@deprecated(since='2.0.0', update_to='paddle.nn.functional.one_hot')
3762
def one_hot(input, depth, allow_out_of_range=False):
3763
    """
3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801

    **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.],
3802
                        [0., 1., 0., 0.],
3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814
                        [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
3815
            The second dimension in X is 5, which is greater than depth.
3816 3817
            Allow_out_of_range =False means that does not allow the word id to exceed depth,
            so it throws an exception.
3818 3819

    Args:
3820 3821 3822
        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.
3823
        depth(scalar): An integer defining the :attr:`depth` of the one hot dimension. If input
3824
            is word id, depth is generally the dictionary size.
3825
        allow_out_of_range(bool): A bool value indicating whether the input
3826 3827 3828 3829
            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.
3830 3831

    Returns:
3832
        Variable: The one-hot representations of input. A Tensor or LoDTensor with type float32.
3833 3834

    Examples:
C
caoying03 已提交
3835
        .. code-block:: python
3836

3837
            import paddle
3838
            import paddle.fluid as fluid
3839 3840
            paddle.enable_static()

3841 3842 3843
            # 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)
3844
    """
J
Jiabin Yang 已提交
3845
    if _non_static_mode():
S
songyouwei 已提交
3846 3847 3848
        if isinstance(depth, Variable):
            depth = depth.numpy()
            assert depth.shape == (
3849 3850
                1,
            ), "depth of type Variable should have shape [1]"
3851
            depth = depth.item(0)
3852 3853 3854
        out = _legacy_C_ops.one_hot(
            input, 'depth', depth, 'allow_out_of_range', allow_out_of_range
        )
3855 3856
        out.stop_gradient = True
        return out
3857

3858
    helper = LayerHelper("one_hot", **locals())
3859
    check_variable_and_dtype(input, 'input', ['int32', 'int64'], 'one_hot')
3860
    check_type(depth, 'depth', (int, Variable), 'one_hot')
X
Xin Pan 已提交
3861
    one_hot_out = helper.create_variable_for_type_inference(dtype='float32')
3862

3863 3864
    if not isinstance(depth, Variable):
        # user attribute
3865
        inputs = {'X': input}
Y
Yi Liu 已提交
3866
        attrs = {'depth': depth, 'allow_out_of_range': allow_out_of_range}
3867
    else:
3868 3869 3870
        depth.stop_gradient = True
        inputs = {'X': input, 'depth_tensor': depth}
        attrs = {'allow_out_of_range': allow_out_of_range}
3871 3872 3873
    helper.append_op(
        type="one_hot", inputs=inputs, attrs=attrs, outputs={'Out': one_hot_out}
    )
3874
    one_hot_out.stop_gradient = True
3875
    return one_hot_out
Y
Yu Yang 已提交
3876 3877


Y
Yu Yang 已提交
3878
def autoincreased_step_counter(counter_name=None, begin=1, step=1):
Y
Yu Yang 已提交
3879
    """
3880 3881
    :api_attr: Static Graph

3882 3883
    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 已提交
3884
    and the step size is 1.
Y
Yu Yang 已提交
3885 3886

    Args:
Y
Yibing Liu 已提交
3887 3888 3889
        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 已提交
3890

3891
    Returns:
Y
Yibing Liu 已提交
3892
        Variable: The auto-increased Variable with data type int64.
Y
yi.wu 已提交
3893 3894 3895 3896

    Examples:
        .. code-block:: python

3897
           import paddle.fluid as fluid
3898 3899
           import paddle
           paddle.enable_static()
Y
yi.wu 已提交
3900
           global_step = fluid.layers.autoincreased_step_counter(
Y
Yibing Liu 已提交
3901
               counter_name='@LR_DECAY_COUNTER@', begin=0, step=1)
Y
Yu Yang 已提交
3902 3903
    """
    helper = LayerHelper('global_step_counter')
Y
Yu Yang 已提交
3904 3905
    if counter_name is None:
        counter_name = '@STEP_COUNTER@'
Y
Yu Yang 已提交
3906
    counter, is_new_var = helper.create_or_get_global_variable(
H
hong 已提交
3907 3908 3909 3910
        name=counter_name,
        dtype='int64',
        shape=[1],
        persistable=True,
3911 3912
        belong_to_optimizer=True,
    )
Y
Yu Yang 已提交
3913
    if is_new_var:
3914 3915 3916
        helper.set_variable_initializer(
            counter, initializer=Constant(value=begin - 1, force_cpu=True)
        )
W
Wu Yi 已提交
3917
        helper.main_program.global_block()._prepend_op(
Y
Yu Yang 已提交
3918 3919
            type='increment',
            inputs={'X': [counter]},
Y
Yu Yang 已提交
3920
            outputs={'Out': [counter]},
3921 3922
            attrs={'step': float(step)},
        )
Y
Yu Yang 已提交
3923 3924 3925
        counter.stop_gradient = True

    return counter
Y
yangyaming 已提交
3926 3927


3928
def unsqueeze(input, axes, name=None):
Y
Yibing Liu 已提交
3929
    """
3930
    Insert single-dimensional entries to the shape of a Tensor. Takes one
M
minqiyang 已提交
3931 3932
    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 已提交
3933

M
minqiyang 已提交
3934
    For example:
H
haowang101779990 已提交
3935 3936 3937

    .. code-block:: text

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

Y
Yibing Liu 已提交
3941
    Args:
3942
        input (Variable): The input Tensor to be unsqueezed. Supported data type: float32, float64, bool, int8, int32, int64.
3943
        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 .
3944
        name (str|None): Name for this layer.
Y
Yibing Liu 已提交
3945 3946

    Returns:
3947
        Variable: Unsqueezed Tensor, with the same data type as input.
Y
Yibing Liu 已提交
3948 3949 3950 3951

    Examples:
        .. code-block:: python

3952 3953 3954
            import paddle.fluid as fluid
            x = fluid.layers.data(name='x', shape=[5, 10])
            y = fluid.layers.unsqueeze(input=x, axes=[1])
3955

Y
Yibing Liu 已提交
3956
    """
J
Jiabin Yang 已提交
3957
    if _non_static_mode():
L
Leo Chen 已提交
3958 3959 3960
        if isinstance(axes, int):
            axes = [axes]
        elif isinstance(axes, Variable):
3961
            axes = axes.numpy().tolist()
L
Leo Chen 已提交
3962 3963 3964 3965 3966
        elif isinstance(axes, (list, tuple)):
            axes = [
                item.numpy().item(0) if isinstance(item, Variable) else item
                for item in axes
            ]
3967
        if _in_legacy_dygraph():
3968
            out, _ = _legacy_C_ops.unsqueeze2(input, 'axes', axes)
3969
            return out
3970
        return _C_ops.unsqueeze(input, axes)
3971 3972

    check_type(axes, 'axis/axes', (int, list, tuple, Variable), 'unsqueeze')
3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989
    check_variable_and_dtype(
        input,
        'input',
        [
            'float16',
            'float32',
            'float64',
            'bool',
            'int8',
            'int16',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        'unsqueeze',
    )
3990 3991 3992 3993 3994 3995 3996 3997 3998 3999
    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 已提交
4000
        if utils._contain_var(axes):
4001
            inputs["AxesTensorList"] = utils._convert_to_tensor_list(axes)
4002 4003 4004
        else:
            attrs["axes"] = axes

X
Xin Pan 已提交
4005 4006
    out = helper.create_variable_for_type_inference(dtype=input.dtype)
    x_shape = helper.create_variable_for_type_inference(dtype=input.dtype)
4007 4008 4009 4010 4011 4012
    helper.append_op(
        type="unsqueeze2",
        inputs=inputs,
        attrs=attrs,
        outputs={"Out": out, "XShape": x_shape},
    )
Y
Yibing Liu 已提交
4013

4014 4015
    return out

4016

Y
yangyaming 已提交
4017
def lod_reset(x, y=None, target_lod=None):
Y
yangyaming 已提交
4018
    """
Y
Yibing Liu 已提交
4019
    Set LoD of :attr:`x` to a new one specified by :attr:`y` or
4020 4021 4022 4023
    :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
4024
    :attr:`y.data` or :attr:`target_lod`, only one level LoD is supported.
Y
yangyaming 已提交
4025 4026 4027 4028 4029 4030

    .. code-block:: text

        * Example 1:

            Given a 1-level LoDTensor x:
4031
                x.lod =  [[ 2,           3,                   1 ]]
Y
yangyaming 已提交
4032 4033 4034
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

4035
            target_lod: [4, 2]
Y
yangyaming 已提交
4036 4037

            then we get a 1-level LoDTensor:
4038
                out.lod =  [[4,                          2]]
Y
yangyaming 已提交
4039 4040 4041 4042 4043 4044
                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:
4045
                x.lod =  [[2,            3,                   1]]
Y
yangyaming 已提交
4046 4047 4048 4049
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

            y is a Tensor:
4050
                y.data = [[2, 4]]
Y
yangyaming 已提交
4051 4052 4053
                y.dims = [1, 3]

            then we get a 1-level LoDTensor:
4054
                out.lod =  [[2,            4]]
Y
yangyaming 已提交
4055 4056 4057 4058 4059 4060
                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:
4061
                x.lod =  [[2,            3,                   1]]
Y
yangyaming 已提交
4062 4063 4064 4065
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

            y is a 2-level LoDTensor:
4066
                y.lod =  [[2, 2], [2, 2, 1, 1]]
Y
yangyaming 已提交
4067 4068 4069 4070
                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:
4071
                out.lod =  [[2, 2], [2, 2, 1, 1]]
Y
yangyaming 已提交
4072 4073 4074 4075
                out.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                out.dims = [6, 1]

    Args:
4076
        x (Variable): Input variable which could be a Tensor or LoDTensor.
4077
                      The data type should be int32, int64, float32 or float64.
4078 4079
        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.
4080 4081
                                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 已提交
4082
                                      as target LoD when :attr:`y` not provided.
Y
yangyaming 已提交
4083 4084

    Returns:
Y
Yibing Liu 已提交
4085
        Variable: Output variable with LoD specified by this layer.
Y
yangyaming 已提交
4086 4087

    Raises:
Y
Yibing Liu 已提交
4088
        ValueError: If :attr:`y` and :attr:`target_lod` are both None.
Y
yangyaming 已提交
4089 4090 4091 4092

    Examples:
        .. code-block:: python

4093
            import paddle.fluid as fluid
4094 4095 4096
            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 已提交
4097
    """
4098 4099 4100
    check_variable_and_dtype(
        x, 'x', ['float32', 'float64', 'int32', 'int64'], 'lod_reset'
    )
Y
yangyaming 已提交
4101
    helper = LayerHelper("lod_reset", **locals())
X
Xin Pan 已提交
4102
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
Y
yangyaming 已提交
4103
    if y is not None:
4104
        check_type(y, 'y', (Variable), 'lod_reset')
4105 4106 4107 4108
        # TODO: check y.lod_level = 0 dtype
        helper.append_op(
            type="lod_reset", inputs={'X': x, 'Y': y}, outputs={'Out': out}
        )
Y
yangyaming 已提交
4109
    elif target_lod is not None:
4110 4111 4112 4113 4114 4115
        helper.append_op(
            type="lod_reset",
            inputs={'X': x},
            attrs={'target_lod': target_lod},
            outputs={'Out': out},
        )
Y
yangyaming 已提交
4116
    else:
4117 4118 4119 4120
        raise ValueError("y and target_lod should not be both none.")
    return out


4121
def pad(x, paddings, pad_value=0.0, name=None):
4122
    r"""
4123
    :alias_main: paddle.nn.functional.pad
4124 4125
        :alias: paddle.nn.functional.pad,paddle.nn.functional.common.pad
        :old_api: paddle.fluid.layers.pad
4126

S
SunGaofeng 已提交
4127 4128
    This op will pad a tensor with a constant value given by :attr:`pad_value`, and the
    padded shape is specified by :attr:`paddings`.
G
guosheng 已提交
4129

S
SunGaofeng 已提交
4130 4131 4132 4133
    Specifically, the number of values padded before the elements of :attr:`x`
    in dimension :attr:`i` is indicated by :attr:`paddings[2*i]`, and the number
    of values padded after the elements of :attr:`x` in dimension :attr:`i` is
    indicated by :attr:`paddings[2*i+1]`.
G
guosheng 已提交
4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151

    See below for an example.

    .. code-block:: text

        Given:
            x = [[1, 2], [3, 4]]

            paddings = [0, 1, 1, 2]

            pad_value = 0

        Return:
            out = [[0, 1, 2, 0, 0]
                   [0, 3, 4, 0, 0]
                   [0, 0, 0, 0, 0]]

    Args:
S
SunGaofeng 已提交
4152
        x (Variable): Tensor, data type is float32.
G
guosheng 已提交
4153
        paddings (list): A list of integers. Its elements specify the padded
S
SunGaofeng 已提交
4154
                         width before and after each dimension in turn.
4155
                         The length of :attr:`paddings` must be equal to
G
guosheng 已提交
4156 4157
                         :math:`rank(x) \\times 2`.
        pad_value (float): The constant value used to pad.
4158 4159
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
4160
                             For more information, please refer to :ref:`api_guide_Name`
G
guosheng 已提交
4161 4162

    Returns:
S
SunGaofeng 已提交
4163 4164 4165 4166
        The padded tensor, with the same data type and rank as :attr:`x`

    Return Type:
        Variable
G
guosheng 已提交
4167 4168 4169

    Examples:
        .. code-block:: python
G
guosheng 已提交
4170

4171
            # x is a rank 2 tensor variable
S
SunGaofeng 已提交
4172
            import paddle.fluid as fluid
4173 4174
            x = fluid.data(name='data', shape=[300, 300], dtype='float32')
            out = fluid.layers.pad(x=x, paddings=[0, 1, 1, 2], pad_value=0.)
G
guosheng 已提交
4175
    """
4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189
    check_variable_and_dtype(
        x,
        'x',
        [
            'float16',
            'float32',
            'float64',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        "pad",
    )
4190

4191 4192 4193 4194
    check_type(pad_value, 'pad_value', (float, int, Variable), 'pad')
    if isinstance(pad_value, int):
        pad_value = float(pad_value)

4195 4196
    helper = LayerHelper('pad', **locals())
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
4197
    out = helper.create_variable_for_type_inference(dtype)
4198 4199 4200 4201 4202 4203
    helper.append_op(
        type='pad',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'paddings': paddings, 'pad_value': pad_value},
    )
G
guosheng 已提交
4204
    return out
4205 4206


4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217
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',
):
4218
    """
4219

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

4222 4223
    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)
4224 4225
    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 已提交
4226
    and the resizing only applies on the three dimensions(depth, height and width).
4227

4228
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in the
4229 4230
    future and only use :attr:`out_shape` instead.

4231
    Supporting resample methods:
4232
        'LINEAR' : Linear interpolation
Q
update  
qiaolongfei 已提交
4233

4234
        'BILINEAR' : Bilinear interpolation
T
Tink_Y 已提交
4235

K
Kaipeng Deng 已提交
4236 4237
        'TRILINEAR' : Trilinear interpolation

4238
        'NEAREST' : Nearest neighbor interpolation
4239

4240
        'BICUBIC' : Bicubic interpolation
4241 4242

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

4245
    Nearest neighbor interpolation is to perform nearest neighbor interpolation
4246
    in both the 3rd dimension(in height direction) and the 4th dimension(in width
4247
    direction) on input tensor.
4248 4249 4250 4251 4252

    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
4253 4254
    again in the other direction.

4255 4256 4257
    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 已提交
4258
    The linear interpolation is performed on three directions.
4259

4260 4261 4262 4263
    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 已提交
4264

4265
    Align_corners and align_mode are optional parameters,the calculation method
4266 4267 4268 4269
    of interpolation can be selected by them.

    Example:

T
Tink_Y 已提交
4270
    .. code-block:: text
4271

T
Tink_Y 已提交
4272
        For scale:
4273

T
Tink_Y 已提交
4274
            if align_corners = True && out_size > 1 :
4275

T
Tink_Y 已提交
4276
              scale_factor = (in_size-1.0)/(out_size-1.0)
4277

T
Tink_Y 已提交
4278
            else:
4279

T
Tink_Y 已提交
4280
              scale_factor = float(in_size/out_size)
4281 4282


T
Tink_Y 已提交
4283
        Nearest neighbor interpolation:
4284

T
Tink_Y 已提交
4285 4286
          if:
              align_corners = False
4287

T
Tink_Y 已提交
4288 4289
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4290

T
Tink_Y 已提交
4291 4292
              H_out = floor (H_{in} * scale_{factor})
              W_out = floor (W_{in} * scale_{factor})
4293

T
Tink_Y 已提交
4294 4295
          else:
              align_corners = True
4296

T
Tink_Y 已提交
4297 4298
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4299

T
Tink_Y 已提交
4300 4301
              H_out = round(H_{in} * scale_{factor})
              W_out = round(W_{in} * scale_{factor})
4302

4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319
        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 已提交
4320 4321 4322 4323
        Bilinear interpolation:

          if:
              align_corners = False , align_mode = 0
4324

T
Tink_Y 已提交
4325 4326
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4327

T
Tink_Y 已提交
4328 4329
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5
4330

T
Tink_Y 已提交
4331
          else:
4332

T
Tink_Y 已提交
4333 4334
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4335

T
Tink_Y 已提交
4336 4337
              H_out = H_{in} * scale_{factor}
              W_out = W_{in} * scale_{factor}
4338

K
Kaipeng Deng 已提交
4339 4340 4341 4342
        Trilinear interpolation:

          if:
              align_corners = False , align_mode = 0
4343

K
Kaipeng Deng 已提交
4344 4345
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:
4346

K
Kaipeng Deng 已提交
4347 4348 4349 4350 4351 4352
              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:
4353

K
Kaipeng Deng 已提交
4354 4355 4356 4357
              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}
4358

4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370
        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 已提交
4371 4372
              H_out = H_{in} * scale_{factor}
              W_out = W_{in} * scale_{factor}
4373

4374

4375 4376
    For details of linear interpolation, please refer to Wikipedia:
    https://en.wikipedia.org/wiki/Linear_interpolation.
4377

4378
    For details of nearest neighbor interpolation, please refer to Wikipedia:
4379
    https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation.
4380

4381
    For details of bilinear interpolation, please refer to Wikipedia:
4382
    https://en.wikipedia.org/wiki/Bilinear_interpolation.
4383

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

4387 4388
    For details of bicubic interpolation, please refer to Wikipedia:
    https://en.wikipedia.org/wiki/Bicubic_interpolation
4389

R
ruri 已提交
4390
    Parameters:
4391
        input (Variable): 3-D, 4-D or 5-D Tensor, its data type is float32, float64, or uint8,
4392
                          its data format is specified by :attr:`data_format`.
4393
        out_shape (list|tuple|Variable|None): Output shape of image resize
4394 4395
             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.
4396
             Default: None. If a list, each element can be an integer or a Tensor Variable of shape: [1].
4397
             If a Tensor Variable, its dimensions size should be a 1.
4398 4399 4400
        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 已提交
4401
             Default: None.
4402 4403
        name(str|None): A name for this layer(optional). If set None, the layer
                        will be named automatically.
4404
        resample(str): The resample method. It supports 'LINEAR', 'BICUBIC', 'BILINEAR', 'TRILINEAR'
K
Kaipeng Deng 已提交
4405
                       and 'NEAREST' currently. Default: 'BILINEAR'
4406 4407 4408
        actual_shape(Variable): An optional input to specify output shape
                                dynamically. If provided, image resize
                                according to this given shape rather than
4409
                                :attr:`out_shape` and :attr:`scale` specifying
4410 4411
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
4412 4413 4414 4415 4416
                                :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 已提交
4417
                                errors would be occurred in graph constructing stage.
4418
                                Default: None
4419 4420
        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
4421 4422
                               corner pixels.
                               Default: True
4423 4424
        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 ,
4425
                            can be \'1\' for src_idx = scale*dst_index.
4426
        data_format (str, optional): Specify the data format of the input, and the data format of the output
4427
            will be consistent with that of the input. An optional string from:`NCW`, `NWC`, `"NCHW"`, `"NHWC"`, `"NCDHW"`,
4428
            `"NDHWC"`. The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
4429
            `[batch_size, input_channels, input_height, input_width]`. When it is `"NCHW"`, the data is stored
4430
            in the order of: `[batch_size, input_channels, input_depth, input_height, input_width]`.
4431 4432

    Returns:
4433
        A 3-D Tensor of the shape (num_batches, channels, out_w) or (num_batches, out_w, channels),
4434 4435
        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 已提交
4436

4437 4438 4439
    Raises:
        TypeError: out_shape should be a list or tuple or Variable.
        TypeError: actual_shape should either be Variable or None.
4440 4441
        ValueError: The 'resample' of image_resize can only be 'LINEAR', 'BILINEAR',
                    'TRILINEAR', 'BICUBIC' or 'NEAREST' currently.
4442
        ValueError: 'LINEAR' only support 3-D tensor.
4443
        ValueError: 'BICUBIC', 'BILINEAR' and 'NEAREST' only support 4-D tensor.
K
Kaipeng Deng 已提交
4444
        ValueError: 'TRILINEAR' only support 5-D tensor.
4445
        ValueError: One of out_shape and scale must not be None.
4446
        ValueError: out_shape length should be 1 for input 3-D tensor.
K
Kaipeng Deng 已提交
4447 4448
        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 已提交
4449
        ValueError: scale should be greater than zero.
T
tianshuo78520a 已提交
4450
        TypeError: align_corners should be a bool value
4451
        ValueError: align_mode can only be '0' or '1'
4452
        ValueError: data_format can only be 'NCW', 'NWC', 'NCHW', 'NHWC', 'NCDHW' or 'NDHWC'.
4453

4454 4455
    Examples:
        .. code-block:: python
4456

4457 4458 4459 4460 4461 4462
            #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 已提交
4463

4464 4465
            #1
            output = fluid.layers.image_resize(input=input,out_shape=[12,12])
R
ruri 已提交
4466

4467 4468 4469 4470 4471
            #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 已提交
4472

4473 4474 4475 4476 4477
            #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 已提交
4478

4479 4480 4481 4482 4483
            #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 已提交
4484

4485 4486 4487
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
4488

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

4491
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
4492 4493 4494
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
4495

4496
            print(output_data[0].shape)
4497

4498 4499 4500 4501 4502 4503 4504 4505
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
4506

4507 4508
            #imperative mode
            import paddle.fluid.dygraph as dg
4509

4510 4511 4512 4513
            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)
4514

4515
                # [2L, 3L, 12L, 12L]
4516

4517
    """
4518
    resample_methods = {
4519
        'LINEAR': 'linear',
4520
        'BILINEAR': 'bilinear',
K
Kaipeng Deng 已提交
4521
        'TRILINEAR': 'trilinear',
4522
        'NEAREST': 'nearest',
4523
        'LINEAR': 'linear',
4524
    }
4525
    resample = resample.upper()
4526 4527
    if resample not in resample_methods:
        raise ValueError(
4528
            "The 'resample' of image_resize can only be 'LINEAR', 'BILINEAR', 'TRILINEAR' "
4529 4530
            "or 'NEAREST' currently."
        )
4531
    resample_type = resample_methods[resample]
4532

4533 4534 4535
    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 已提交
4536
        raise ValueError("'BILINEAR' and 'NEAREST' only support 4-D tensor.")
4537
    elif resample == 'TRILINEAR' and len(input.shape) != 5:
K
Kaipeng Deng 已提交
4538 4539
        raise ValueError("'TRILINEAR'only support 5-D tensor.")

4540 4541 4542 4543 4544
    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")

4545
    if out_shape is None and scale is None:
4546
        raise ValueError("One of out_shape and scale must not be None.")
4547
    helper = LayerHelper('{}_interp'.format(resample_type), **locals())
4548
    dtype = helper.input_dtype()
4549

4550
    if len(input.shape) == 3 and data_format not in ['NCW', 'NWC']:
4551
        raise ValueError(
4552 4553 4554 4555
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCW` or `NWC` supported for 3-D input."
        )
4556
    elif len(input.shape) == 4 and data_format not in ['NCHW', 'NHWC']:
4557
        raise ValueError(
4558 4559 4560 4561
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCHW` or `NHWC` supported for 4-D input."
        )
4562 4563
    elif len(input.shape) == 5 and data_format not in ['NCDHW', 'NDHWC']:
        raise ValueError(
4564 4565 4566 4567
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCDHW` or `NDHWC` supported for 5-D input."
        )
4568

4569
    def _is_list_or_turple_(data):
4570
        return isinstance(data, list) or isinstance(data, tuple)
4571

4572
    if data_format == 'NCHW' or data_format == 'NCDHW' or data_format == 'NCW':
4573
        data_layout = 'NCHW'
4574
    if data_format == 'NHWC' or data_format == 'NDHWC' or data_format == 'NWC':
4575 4576
        data_layout = 'NHWC'

4577
    inputs = {"X": input}
D
dengkaipeng 已提交
4578
    attrs = {
4579 4580 4581
        "out_d": -1,
        "out_h": -1,
        "out_w": -1,
D
dengkaipeng 已提交
4582 4583
        "interp_method": resample_type,
        "align_corners": align_corners,
4584
        "align_mode": align_mode,
4585
        "data_layout": data_layout,
D
dengkaipeng 已提交
4586 4587
    }

4588
    if out_shape is not None:
4589
        if isinstance(out_shape, Variable) and not _non_static_mode():
4590
            out_shape.stop_gradient = True
4591
            inputs['OutSize'] = out_shape
4592
        else:
4593 4594 4595 4596 4597 4598 4599 4600
            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]
4601
            if not (_is_list_or_turple_(out_shape)):
D
dengkaipeng 已提交
4602
                raise TypeError(
4603 4604
                    "out_shape should be a list or tuple or Variable."
                )
4605 4606 4607 4608 4609 4610
            # Validate the shape
            contain_var = False
            for dim_idx, dim_size in enumerate(out_shape):
                if isinstance(dim_size, Variable):
                    contain_var = True
                    continue
4611 4612 4613
                assert (
                    dim_size > 0
                ), "Each dimension size given in out_shape must be greater than 0."
4614 4615 4616 4617 4618 4619 4620 4621 4622 4623

            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:
4624
                        assert isinstance(dim, int)
4625
                        temp_out = helper.create_variable_for_type_inference(
4626 4627 4628 4629 4630
                            'int32'
                        )
                        fill_constant(
                            [1], 'int32', dim, force_cpu=True, out=temp_out
                        )
4631 4632 4633 4634
                        new_size_tensor.append(temp_out)
                        size_list.append(dim)
                inputs['SizeTensor'] = new_size_tensor

4635 4636
            if len(input.shape) == 3:
                if len(out_shape) != 1:
4637 4638 4639
                    raise ValueError(
                        "out_shape length should be 1 for " "input 3-D tensor."
                    )
4640 4641 4642 4643 4644 4645
                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 已提交
4646
                if len(out_shape) != 2:
4647 4648 4649
                    raise ValueError(
                        "out_shape length should be 2 for " "input 4-D tensor."
                    )
4650 4651 4652 4653 4654 4655 4656
                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 已提交
4657 4658
            if len(input.shape) == 5:
                if len(out_shape) != 3:
4659 4660 4661
                    raise ValueError(
                        "out_shape length should be 3 for " "input 5-D tensor."
                    )
4662 4663 4664 4665 4666 4667 4668 4669 4670
                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]
4671

4672
    else:
4673 4674 4675
        if _non_static_mode() and isinstance(scale, Variable):
            scale = scale.numpy()
        elif isinstance(scale, Variable):
4676 4677
            scale.stop_gradient = True
            inputs["Scale"] = scale
4678
        elif isinstance(scale, float) or isinstance(scale, int):
4679
            if scale <= 0:
4680
                raise ValueError("Attr(scale) should be greater than zero.")
4681
            attrs['scale'] = float(scale)
4682 4683
        else:
            raise TypeError(
4684 4685
                "Attr(scale)'s type should be float, int or Variable."
            )
4686

4687
    if isinstance(actual_shape, Variable):
4688 4689 4690 4691 4692
        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
4693 4694 4695
        inputs["OutSize"] = actual_shape
    elif actual_shape is not None:
        raise TypeError("actual_shape should either be Variable or None.")
4696 4697 4698 4699 4700 4701 4702 4703 4704

    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":
4705
            out = _legacy_C_ops.linear_interp(input, actual_shape, *dy_attr)
4706
        elif resample_type == "bilinear":
4707
            out = _legacy_C_ops.bilinear_interp(input, actual_shape, *dy_attr)
4708
        elif resample_type == "trilinear":
4709
            out = _legacy_C_ops.trilinear_interp(input, actual_shape, *dy_attr)
4710
        elif resample_type == "nearest":
4711
            out = _legacy_C_ops.nearest_interp(input, actual_shape, *dy_attr)
4712
        elif resample_type == "bicubic":
4713
            out = _legacy_C_ops.bicubic_interp(input, actual_shape, *dy_attr)
4714 4715
        return out

X
Xin Pan 已提交
4716
    out = helper.create_variable_for_type_inference(dtype)
4717 4718 4719 4720 4721 4722
    helper.append_op(
        type='{}_interp'.format(resample_type),
        inputs=inputs,
        outputs={"Out": out},
        attrs=attrs,
    )
4723
    return out
F
stash  
fengjiayi 已提交
4724 4725


4726
@templatedoc(op_type="bilinear_interp")
4727 4728 4729 4730 4731 4732 4733 4734 4735 4736
def resize_bilinear(
    input,
    out_shape=None,
    scale=None,
    name=None,
    actual_shape=None,
    align_corners=True,
    align_mode=1,
    data_format='NCHW',
):
4737
    """
4738

R
ruri 已提交
4739
    This op resizes the input by performing bilinear interpolation based on given
4740
    output shape which specified by actual_shape, out_shape and scale
4741 4742
    in priority order.

4743
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in
4744 4745
    the future and only use :attr:`out_shape` instead.

4746 4747 4748 4749
    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
4750 4751
    again in the other direction.

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

4755
    Align_corners and align_mode are optional parameters,the calculation
4756 4757 4758 4759
    method of interpolation can be selected by them.

    Example:

T
Tink_Y 已提交
4760
    .. code-block:: text
4761

T
Tink_Y 已提交
4762
        For scale:
4763

T
Tink_Y 已提交
4764
            if align_corners = True && out_size > 1 :
4765

T
Tink_Y 已提交
4766
              scale_factor = (in_size-1.0)/(out_size-1.0)
4767

T
Tink_Y 已提交
4768
            else:
4769

4770
              scale_factor = float(in_size/out_size)
4771

T
Tink_Y 已提交
4772 4773 4774 4775
        Bilinear interpolation:

          if:
              align_corners = False , align_mode = 0
4776

T
Tink_Y 已提交
4777 4778
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4779

T
Tink_Y 已提交
4780 4781
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5
4782

T
Tink_Y 已提交
4783
          else:
T
tink2123 已提交
4784

T
Tink_Y 已提交
4785 4786 4787 4788
              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}
4789

R
ruri 已提交
4790 4791
    Parameters:
        input(Variable): 4-D Tensor(NCHW), its data type is float32, float64, or uint8,
4792
                          its data format is specified by :attr:`data_format`.
D
dengkaipeng 已提交
4793
        out_shape(list|tuple|Variable|None): Output shape of resize bilinear
4794 4795
            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
4796
            Tensor Variable, its dimension size should be 1.
4797
        scale(float|Variable|None): The multiplier for the input height or width. At
4798 4799
             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 已提交
4800
             Default: None.
4801 4802 4803
        actual_shape(Variable): An optional input to specify output shape
                                dynamically. If provided, image resize
                                according to this given shape rather than
4804
                                :attr:`out_shape` and :attr:`scale` specifying
4805 4806
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
4807 4808 4809 4810 4811
                                :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 已提交
4812
                                errors would be occurred in graph constructing stage.
4813
                                Default: None
4814 4815
        align_corners(bool): ${align_corners_comment}
        align_mode(bool): ${align_mode_comment}
4816
        data_format (str, optional): Specify the data format of the input, and the data format of the output
4817 4818 4819
            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 已提交
4820
        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 已提交
4821 4822

    Returns:
4823
        Variable: 4-D tensor(NCHW or NHWC).
4824

4825 4826
    Examples:
        .. code-block:: python
4827

4828 4829 4830 4831 4832 4833
            #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 已提交
4834

4835 4836
            #1
            output = fluid.layers.resize_bilinear(input=input,out_shape=[12,12])
R
ruri 已提交
4837

4838 4839 4840 4841 4842
            #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 已提交
4843

4844 4845 4846 4847 4848
            #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 已提交
4849

4850 4851 4852 4853 4854
            #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 已提交
4855

4856 4857 4858
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
4859

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

4862
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
4863 4864 4865
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
4866

4867
            print(output_data[0].shape)
4868

4869 4870 4871 4872 4873 4874 4875 4876
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
4877

4878 4879
            #imperative mode
            import paddle.fluid.dygraph as dg
4880

4881 4882 4883 4884
            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)
4885

4886
                # [2L, 3L, 12L, 12L]
4887

4888 4889
    """

4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'BILINEAR',
        actual_shape,
        align_corners,
        align_mode,
        data_format,
    )
4901 4902


K
Kaipeng Deng 已提交
4903
@templatedoc(op_type="trilinear_interp")
4904 4905 4906 4907 4908 4909 4910 4911 4912 4913
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 已提交
4914
    """
4915

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

4920
    **Warning:** the parameter :attr:`actual_shape` will be deprecated
4921 4922
    in the future and only use :attr:`out_shape` instead.

4923 4924 4925
    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 已提交
4926 4927 4928 4929 4930
    The linear interpolation is performed on three directions.

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

4931
    Align_corners and align_mode are optional parameters,the calculation
K
Kaipeng Deng 已提交
4932 4933 4934 4935 4936 4937 4938
    method of interpolation can be selected by them.

    Example:

    .. code-block:: text

        For scale:
4939

K
Kaipeng Deng 已提交
4940 4941 4942
            if align_corners = True && out_size > 1 :

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

K
Kaipeng Deng 已提交
4944
            else:
4945 4946

              scale_factor = float(in_size/out_size)
K
Kaipeng Deng 已提交
4947 4948 4949 4950

        Bilinear interpolation:

          if:
4951

K
Kaipeng Deng 已提交
4952
              align_corners = False , align_mode = 0
4953

K
Kaipeng Deng 已提交
4954 4955
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:
4956

K
Kaipeng Deng 已提交
4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969
              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 已提交
4970
    Parameters:
4971 4972
        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 已提交
4973
        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.
4974
        scale(float|Variable|None): The multiplier for the input depth, height or width.
4975 4976
             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 已提交
4977
             Default: None.
R
ruri 已提交
4978
        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 已提交
4979 4980 4981 4982 4983 4984
        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
4985 4986 4987 4988 4989
                                :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 已提交
4990
                                errors would be occurred in graph constructing stage.
K
Kaipeng Deng 已提交
4991 4992 4993
                                Default: None
        align_corners(bool): ${align_corners_comment}
        align_mode(bool): ${align_mode_comment}
4994
        data_format (str, optional): Specify the data format of the input, and the data format of the output
4995 4996 4997
            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 已提交
4998 4999

    Returns:
5000
        Variable: A 5-D Tensor(NCDHW or NDHWC)
K
Kaipeng Deng 已提交
5001 5002 5003

    Examples:
        .. code-block:: python
5004

5005 5006 5007 5008 5009 5010
            #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 已提交
5011

5012 5013
            #1
            output = fluid.layers.resize_trilinear(input=input,out_shape=[12,12,12])
R
ruri 已提交
5014

5015 5016 5017 5018 5019
            #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 已提交
5020

5021 5022 5023 5024 5025
            #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 已提交
5026

5027 5028 5029 5030 5031
            #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 已提交
5032

5033 5034 5035
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5036

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

5039
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
5040 5041 5042
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
5043

5044
            print(output_data[0].shape)
R
ruri 已提交
5045

5046 5047 5048 5049 5050 5051 5052 5053
            #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 已提交
5054

5055 5056
            #imperative mode
            import paddle.fluid.dygraph as dg
5057

5058 5059 5060 5061
            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)
5062

5063
                # [2L, 3L, 12L, 12L, 12L]
5064 5065 5066



K
Kaipeng Deng 已提交
5067 5068
    """

5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'TRILINEAR',
        actual_shape,
        align_corners,
        align_mode,
        data_format,
    )
K
Kaipeng Deng 已提交
5080 5081


5082
@templatedoc(op_type="nearest_interp")
5083 5084 5085 5086 5087 5088 5089 5090 5091
def resize_nearest(
    input,
    out_shape=None,
    scale=None,
    name=None,
    actual_shape=None,
    align_corners=True,
    data_format='NCHW',
):
5092
    """
5093

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

5098
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in the
5099 5100
    future and only use :attr:`out_shape` instead.

5101 5102
    Example:

T
Tink_Y 已提交
5103 5104 5105
    .. code-block:: text

        For scale:
5106

T
Tink_Y 已提交
5107 5108
            if align_corners = True && out_size > 1 :
              scale_factor = (in_size-1.0)/(out_size-1.0)
5109

T
Tink_Y 已提交
5110
            else:
5111

T
Tink_Y 已提交
5112
              scale_factor = float(in_size/out_size)
5113

T
Tink_Y 已提交
5114
        Nearest neighbor interpolation:
5115

T
Tink_Y 已提交
5116 5117
          if:
              align_corners = False
5118

T
Tink_Y 已提交
5119 5120
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5121

T
Tink_Y 已提交
5122 5123
              H_out = floor(H_{in} * scale_{factor})
              W_out = floor(W_{in} * scale_{factor})
5124

T
Tink_Y 已提交
5125 5126
          else:
              align_corners = True
5127

T
Tink_Y 已提交
5128 5129
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5130

T
Tink_Y 已提交
5131 5132
              H_out = round(H_{in} * scale_{factor})
              W_out = round(W_{in} * scale_{factor})
5133 5134


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

R
ruri 已提交
5138
    Parameters:
5139 5140
        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 已提交
5141
        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.
5142
        scale(float|Variable|None): The multiplier for the input height or width. At
5143 5144 5145
             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 已提交
5146
        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`
5147
        actual_shape(Variable): An optional input to specify output shape
5148 5149
                                dynamically. If provided, image resize
                                according to this given shape rather than
5150
                                :attr:`out_shape` and :attr:`scale` specifying
5151 5152
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
5153 5154 5155 5156 5157
                                :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 已提交
5158
                                errors would be occurred in graph constructing stage.
5159
                                Default: None
5160
        align_corners(bool): ${align_corners_comment}
5161
        data_format (str, optional): Specify the data format of the input, and the data format of the output
5162 5163 5164
            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 已提交
5165 5166

    Returns:
5167
        Variable: 4-D tensor(NCHW or NHWC).
5168 5169 5170

    Examples:
        .. code-block:: python
5171

5172 5173 5174 5175 5176
            #declarative mode
            import paddle.fluid as fluid
            import numpy as np
            import paddle
            paddle.enable_static()
5177

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

5180 5181
            #1
            output = fluid.layers.resize_nearest(input=input,out_shape=[12,12])
R
ruri 已提交
5182

5183 5184 5185 5186 5187
            #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 已提交
5188

5189 5190 5191 5192 5193
            #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 已提交
5194

5195 5196 5197 5198 5199
            #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 已提交
5200

5201 5202 5203
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5204

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

5207
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
5208 5209 5210
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
5211

5212
            print(output_data[0].shape)
R
ruri 已提交
5213

5214 5215 5216 5217 5218 5219 5220 5221
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
5222

5223 5224
            #imperative mode
            import paddle.fluid.dygraph as dg
5225

5226 5227 5228 5229
            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 已提交
5230

5231
                # [2L, 3L, 12L, 12L]
5232 5233 5234



5235 5236
    """

5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'NEAREST',
        actual_shape,
        align_corners,
        align_mode=1,
        data_format=data_format,
    )
5248 5249


5250
def log(x, name=None):
5251
    r"""
W
wanghaoshuang 已提交
5252 5253 5254 5255
    Calculates the natural log of the given input tensor, element-wise.

    .. math::

5256
        Out = \\ln(x)
W
wanghaoshuang 已提交
5257 5258

    Args:
S
Steffy-zxf 已提交
5259
        x (Tensor): Input Tensor. Must be one of the following types: float32, float64.
W
Wilber 已提交
5260
        name (str|None): 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`
5261

W
wanghaoshuang 已提交
5262 5263

    Returns:
S
Steffy-zxf 已提交
5264
        Tensor: The natural log of the input Tensor computed element-wise.
W
wanghaoshuang 已提交
5265 5266 5267 5268 5269

    Examples:

        .. code-block:: python

S
Steffy-zxf 已提交
5270
            import paddle
W
Wilber 已提交
5271

S
Steffy-zxf 已提交
5272 5273 5274 5275
            x = [[2,3,4], [7,8,9]]
            x = paddle.to_tensor(x, dtype='float32')
            res = paddle.log(x)
            # [[0.693147, 1.09861, 1.38629], [1.94591, 2.07944, 2.19722]]
W
wanghaoshuang 已提交
5276
    """
5277
    if in_dygraph_mode():
W
wanghuancoder 已提交
5278
        return _C_ops.log(x)
5279 5280
    if _in_legacy_dygraph():
        return _legacy_C_ops.log(x)
5281

5282
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], "log")
5283
    inputs = {'X': [x]}
W
wanghaoshuang 已提交
5284
    helper = LayerHelper('log', **locals())
W
wanghaoshuang 已提交
5285
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
5286
    out = helper.create_variable_for_type_inference(dtype)
W
wanghaoshuang 已提交
5287
    helper.append_op(type="log", inputs={"X": x}, outputs={"Out": out})
W
wanghaoshuang 已提交
5288 5289 5290
    return out


5291
@deprecated(since="2.0.0", update_to="paddle.nn.functional.relu")
5292
def relu(x, name=None):
W
wanghaoshuang 已提交
5293
    """
Z
zhupengyang 已提交
5294
    ${comment}
W
wanghaoshuang 已提交
5295 5296

    Args:
Z
zhupengyang 已提交
5297 5298 5299 5300
        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 已提交
5301 5302

    Returns:
Z
zhupengyang 已提交
5303
        Variable: ${out_comment}
W
wanghaoshuang 已提交
5304 5305 5306 5307 5308

    Examples:

        .. code-block:: python

5309
            import paddle.fluid as fluid
Z
zhupengyang 已提交
5310 5311 5312 5313 5314 5315 5316
            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. ]
5317
                #  [1.  2.6]]"""
5318 5319

    if in_dygraph_mode():
W
wanghuancoder 已提交
5320
        return _C_ops.relu(x)
5321 5322
    if _in_legacy_dygraph():
        return _legacy_C_ops.relu(x)
5323

5324 5325
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'relu')

5326
    inputs = {'X': [x]}
W
wanghaoshuang 已提交
5327
    helper = LayerHelper('relu', **locals())
W
wanghaoshuang 已提交
5328
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
5329
    out = helper.create_variable_for_type_inference(dtype)
5330 5331 5332
    helper.append_op(
        type="relu", inputs={"X": helper.input('x')}, outputs={"Out": out}
    )
W
wanghaoshuang 已提交
5333
    return out
5334 5335


Z
zhupengyang 已提交
5336
@deprecated(since="2.0.0", update_to="paddle.static.nn.prelu")
5337
def prelu(x, mode, param_attr=None, data_format="NCHW", name=None):
5338
    r"""
U
ustiniankw 已提交
5339

Z
zhupengyang 已提交
5340
    prelu activation.
J
jerrywgz 已提交
5341

H
haowang101779990 已提交
5342
    .. math::
S
sunzhongkai588 已提交
5343
        prelu(x) = max(0, x) + \alpha * min(0, x)
J
jerrywgz 已提交
5344

J
jerrywgz 已提交
5345 5346 5347 5348 5349 5350 5351 5352
    There are three modes for the activation:

    .. code-block:: text

        all: All elements share same alpha.
        channel: Elements in same channel share same alpha.
        element: All elements do not share alpha. Each element has its own alpha.

Z
zhupengyang 已提交
5353 5354
    Parameters:
        x (Tensor): The input Tensor or LoDTensor with data type float32.
5355
        mode (str): The mode for weight sharing.
U
ustiniankw 已提交
5356 5357 5358
        param_attr (ParamAttr|None, optional): The parameter attribute for the learnable
            weight (alpha), it can be create by ParamAttr. None by default.
            For detailed information, please refer to :ref:`api_fluid_ParamAttr`.
5359 5360
        data_format(str, optional): Data format that specifies the layout of input.
            It may be "NC", "NCL", "NCHW", "NCDHW", "NLC", "NHWC" or "NDHWC". Default: "NCHW".
U
ustiniankw 已提交
5361 5362
        name (str, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.
J
jerrywgz 已提交
5363 5364

    Returns:
U
ustiniankw 已提交
5365
        Tensor, A tensor with the same shape and data type as x.
J
jerrywgz 已提交
5366 5367 5368 5369

    Examples:
        .. code-block:: python

5370
            import paddle
Z
zhupengyang 已提交
5371 5372 5373 5374 5375

            x = paddle.to_tensor([-1., 2., 3.])
            param = paddle.ParamAttr(initializer=paddle.nn.initializer.Constant(0.2))
            out = paddle.static.nn.prelu(x, 'all', param)
            # [-0.2, 2., 3.]
J
jerrywgz 已提交
5376

J
jerrywgz 已提交
5377
    """
G
Guoxia Wang 已提交
5378
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'prelu')
5379

J
jerrywgz 已提交
5380 5381 5382
    helper = LayerHelper('prelu', **locals())
    if mode not in ['all', 'channel', 'element']:
        raise ValueError('mode should be one of all, channel, element.')
5383

J
jerrywgz 已提交
5384 5385
    alpha_shape = [1]
    if mode == 'channel':
5386 5387

        true_data_format = [
5388 5389 5390 5391 5392 5393 5394
            'NC',
            'NCL',
            'NCHW',
            'NCDHW',
            'NLC',
            'NHWC',
            'NDHWC',
5395 5396 5397 5398
        ]
        if data_format not in true_data_format:
            raise ValueError(
                "data_format must be one of 'NC', 'NCL', 'NCHW', 'NCDHW', "
5399 5400
                "'NLC', 'NHWC', 'NDHWC' but receive {}".format(data_format)
            )
5401 5402 5403

        data_format = 'NCHW' if data_format[1] == 'C' else 'NHWC'

5404 5405 5406 5407
        assert (
            len(x.shape) >= 2
        ), "The size of input shape should be equal or larger than 2 in prelu() when mode is 'channel'"
        # NOTE(zhiqiu): The alpha_shape should be [1, channel] + [1] * len(x.shape[2:]).
5408
        # To be consistent with Prelu, it is simplified.
5409 5410
        # NOTE(zhiqiu): Revert shape to [1, channel, 1, 1] for compatibility with saved model of old version.
        # NOTE(GuoxiaWang): support NHWC data format
5411
        if data_format == 'NHWC':
5412
            alpha_shape = [1, 1, 1, x.shape[-1]]
5413 5414 5415
        else:
            alpha_shape = [1, x.shape[1], 1, 1]

J
jerrywgz 已提交
5416
    elif mode == 'element':
5417 5418 5419
        assert (
            len(x.shape) >= 1
        ), "The size of input shape should be equal or larger than 1 in prelu() when mode is 'element'"
5420
        alpha_shape = [1] + list(x.shape)[1:]
J
jerrywgz 已提交
5421
    dtype = helper.input_dtype(input_param_name='x')
5422 5423 5424 5425 5426 5427 5428
    alpha = helper.create_parameter(
        attr=helper.param_attr,
        shape=alpha_shape,
        dtype=dtype,
        is_bias=False,
        default_initializer=Constant(0.25),
    )
5429 5430 5431
    if in_dygraph_mode():
        return _C_ops.prelu(x, alpha, data_format, mode)

X
Xin Pan 已提交
5432
    out = helper.create_variable_for_type_inference(dtype)
5433 5434 5435 5436 5437 5438
    helper.append_op(
        type="prelu",
        inputs={"X": x, 'Alpha': alpha},
        attrs={"mode": mode, "data_format": data_format},
        outputs={"Out": out},
    )
5439 5440 5441
    return out


G
fix  
gongweibao 已提交
5442 5443 5444
from paddle.fluid.framework import convert_np_dtype_to_dtype_


5445
@deprecated(since="2.0.0", update_to="paddle.normal")
G
gongweibao 已提交
5446
@templatedoc()
5447 5448 5449
def gaussian_random(
    shape, mean=0.0, std=1.0, seed=0, dtype='float32', name=None
):
G
fix  
gongweibao 已提交
5450
    """
5451 5452
    This OP returns a Tensor filled with random values sampled from a Gaussian
    distribution, with ``shape`` and ``dtype``.
G
fix  
gongweibao 已提交
5453 5454

    Args:
5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469
        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 已提交
5470 5471

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

5475
    Examples:
5476
       .. code-block:: python
5477

5478
            import paddle
5479
            import paddle.fluid as fluid
5480
            paddle.enable_static()
5481 5482

            # example 1:
5483
            # attr shape is a list which doesn't contain Tensor.
5484
            result_1 = fluid.layers.gaussian_random(shape=[3, 4])
5485 5486 5487
            # [[-0.31261674,  1.8736548,  -0.6274357,   0.96988016],
            #  [-0.12294637,  0.9554768,   1.5690808,  -1.2894802 ],
            #  [-0.60082096, -0.61138713,  1.5345167,  -0.21834975]]
5488 5489

            # example 2:
5490 5491 5492
            # 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)
5493
            result_2 = fluid.layers.gaussian_random(shape=[dim_1, dim_2])
5494 5495
            # [[ 0.51398206, -0.3389769,   0.23597084],
            #  [ 1.0388143,  -1.2015356,  -1.0499583 ]]
5496 5497

            # example 3:
5498
            # attr shape is a Tensor, the data type must be int64 or int32.
5499 5500
            var_shape = fluid.data(name='var_shape', shape=[2], dtype="int64")
            result_3 = fluid.layers.gaussian_random(var_shape)
5501 5502 5503 5504
            # if var_shape's value is [2, 3]
            # result_3 is:
            # [[-0.12310527,  0.8187662,   1.923219  ]
            #  [ 0.70721835,  0.5210541,  -0.03214082]]
5505

5506
       .. code-block:: python
5507

5508 5509
           # declarative mode
           # required: skiptest
5510 5511
           import numpy as np
           from paddle import fluid
5512

5513
           x = fluid.layers.gaussian_random((2, 3), std=2., seed=10)
5514

5515 5516 5517 5518
           place = fluid.CPUPlace()
           exe = fluid.Executor(place)
           start = fluid.default_startup_program()
           main = fluid.default_main_program()
5519

5520 5521
           exe.run(start)
           x_np, = exe.run(main, feed={}, fetch_list=[x])
5522

5523 5524 5525 5526 5527 5528 5529 5530 5531 5532
           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
5533

5534 5535 5536
           place = fluid.CPUPlace()
           with dg.guard(place) as g:
               x = fluid.layers.gaussian_random((2, 4), mean=2., dtype="float32", seed=10)
5537
               x_np = x.numpy()
5538 5539 5540
           x_np
           # array([[2.3060477 , 2.676496  , 3.9911983 , 0.9990833 ],
           #        [2.8675377 , 2.2279181 , 0.79029655, 2.8447366 ]], dtype=float32)
G
fix  
gongweibao 已提交
5541
    """
5542 5543
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
5544

5545 5546 5547
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
        place = _current_expected_place()
5548
        return _C_ops.gaussian(
5549 5550
            shape, float(mean), float(std), seed, dtype, place
        )
5551 5552

    if _in_legacy_dygraph():
5553
        shape = utils.convert_shape_to_list(shape)
5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565
        return _legacy_C_ops.gaussian_random(
            'shape',
            shape,
            'mean',
            float(mean),
            'std',
            float(std),
            'seed',
            seed,
            'dtype',
            dtype,
        )
5566 5567 5568

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

    inputs = {}
5571 5572 5573 5574
    attrs = {
        'mean': mean,
        'std': std,
        'seed': seed,
5575
        'dtype': dtype,
5576
        'use_mkldnn': False,
5577
    }
5578 5579 5580
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='gaussian_random/randn'
    )
5581

5582 5583
    helper = LayerHelper('gaussian_random', **locals())
    out = helper.create_variable_for_type_inference(dtype)
5584 5585 5586
    helper.append_op(
        type='gaussian_random', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
G
fix  
gongweibao 已提交
5587 5588 5589 5590

    return out


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

R
ruri 已提交
5596 5597 5598 5599
    Parameters:
        x (Variable): 2-D tensor, [batch_size, input_feature_dimensions]
        min (Float): minimum , default 0.0.
        max (Float): maximum, default 1.0.
5600
        seed (Float): Random seed, default 0. if seed is not 0, will generate same number every time.
G
fix  
gongweibao 已提交
5601
        dtype(np.dtype|core.VarDesc.VarType|str): The type of output data : float32, float_16, int etc
G
fix  
gongweibao 已提交
5602 5603

    Returns:
R
ruri 已提交
5604
        Variable: sampling tensor.
G
fix  
gongweibao 已提交
5605

5606 5607 5608
    Examples:
        .. code-block:: python

5609
            import paddle.fluid as fluid
R
ruri 已提交
5610
            x = fluid.data(
5611 5612
                name="X",
                shape=[13, 11],
R
ruri 已提交
5613
                dtype='float32')
5614

Y
Yibing Liu 已提交
5615
            out = fluid.layers.sampling_id(x)
G
fix  
gongweibao 已提交
5616 5617 5618
    """

    helper = LayerHelper('sampling_id', **locals())
X
Xin Pan 已提交
5619
    out = helper.create_variable_for_type_inference(dtype)
5620 5621 5622 5623 5624 5625
    helper.append_op(
        type='sampling_id',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'min': min, 'max': max, 'seed': seed},
    )
G
fix  
gongweibao 已提交
5626 5627 5628 5629

    return out


G
gongweibao 已提交
5630
@templatedoc()
X
Xin Pan 已提交
5631
def sum(x):
G
fix  
gongweibao 已提交
5632
    """
G
gongweibao 已提交
5633
    ${comment}
5634

5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663
    Case 1:
    ::
        Input:
            Input. Shape = [2, 3]
            Input = [[1, 2, 3],
                     [4, 5, 6]]

        Output:
            The output. Shape = [2, 3]
            Output = [[1, 2, 3],
                      [4, 5, 6]]

    Case 2:
    ::
        Input:
            First input:
            Input1. Shape = [2, 3]
            Input1 = [[1, 2, 3],
                      [4, 5, 6]]

        The second input:
            Input2. Shape = [2, 3]
            Input2 = [[7, 8, 9],
                      [10, 11, 12]]

        Output:
            The output. Shape = [2, 3]
            Output = [[8, 10, 12],
                      [14, 16, 18]]
G
fix  
gongweibao 已提交
5664 5665

    Args:
5666
        x (Variable|list(Variable)): ${x_comment}
G
fix  
gongweibao 已提交
5667 5668

    Returns:
5669
        Variable: ${out_comment}
5670 5671 5672 5673

    Examples:
        .. code-block:: python

5674
            import paddle.fluid as fluid
5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693

            input0 = fluid.layers.fill_constant(shape=[2, 3], dtype='int64', value=5)
            input1 = fluid.layers.fill_constant(shape=[2, 3], dtype='int64', value=3)
            sum = fluid.layers.sum([input0, input1])

            # You can print out 'sum' via executor.
            out = fluid.layers.Print(sum, message="the sum of input0 and input1: ")
            exe = fluid.Executor(fluid.CPUPlace())
            exe.run(fluid.default_main_program())

            # The printed result is:
            # 1570701754	the sum of input0 and input1: 	The place is:CPUPlace
            # Tensor[sum_0.tmp_0]
            #    shape: [2,3,]
            #    dtype: l
            #    data: 8,8,8,8,8,8,

            # the sum of input0 and input1 is 2-D Tensor with shape [2,3].
            # dtype is the corresponding C++ data type, which may vary in different environments.
5694 5695
            # Eg: if the data type of tensor is int64, then the corresponding C++ data type is int64_t,
            #       so the dtype value is typeid(int64_t).Name(), which is 'x' on MacOS, 'l' on Linux,
5696
            #       and '__int64' on Windows. They both represent 64-bit integer variables.
G
fix  
gongweibao 已提交
5697 5698
    """

S
Steffy-zxf 已提交
5699
    return paddle.add_n(x)
G
fix  
gongweibao 已提交
5700 5701 5702 5703


def shape(input):
    """
5704
    :alias_main: paddle.shape
5705 5706
        :alias: paddle.shape,paddle.tensor.shape,paddle.tensor.attribute.shape
        :old_api: paddle.fluid.layers.shape
5707

C
chengduozh 已提交
5708 5709
    **Shape Layer**

C
fix doc  
chengduozh 已提交
5710
    Get the shape of the input.
G
fix  
gongweibao 已提交
5711

5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728
    .. 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 已提交
5729
    Args:
5730
        input (Variable): The input can be N-D Tensor or SelectedRows with data type bool, float16, float32, float64, int32, int64.
5731
                          If input variable is type of SelectedRows, returns the shape of it's inner tensor.
G
fix  
gongweibao 已提交
5732 5733

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

5736 5737 5738
    Examples:
        .. code-block:: python

5739
            import paddle.fluid as fluid
5740
            import numpy as np
W
Wilber 已提交
5741 5742
            import paddle
            paddle.enable_static()
5743

5744
            inputs = fluid.data(name="x", shape=[3, 100, 100], dtype="float32")
5745 5746 5747 5748 5749 5750 5751 5752 5753
            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 已提交
5754
    """
5755
    if in_dygraph_mode():
5756
        out = _C_ops.shape(input)
5757 5758 5759
        out.stop_gradient = True
        return out
    if _in_legacy_dygraph():
5760
        out = _legacy_C_ops.shape(input)
W
Wilber 已提交
5761 5762 5763
        out.stop_gradient = True
        return out

5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778
    check_variable_and_dtype(
        input,
        'input',
        [
            'bool',
            'float16',
            'float32',
            'float64',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        'shape',
    )
G
fix  
gongweibao 已提交
5779
    helper = LayerHelper('shape', **locals())
5780
    out = helper.create_variable_for_type_inference(dtype='int32')
5781 5782 5783 5784 5785 5786
    helper.append_op(
        type='shape',
        inputs={'Input': input},
        outputs={'Out': out},
        stop_gradient=True,
    )
G
fix  
gongweibao 已提交
5787 5788

    return out
G
merge  
gongweibao 已提交
5789 5790


S
sneaxiy 已提交
5791 5792 5793 5794
def _elementwise_op(helper):
    op_type = helper.layer_type
    x = helper.kwargs.get('x', None)
    y = helper.kwargs.get('y', None)
X
Xin Pan 已提交
5795

S
sneaxiy 已提交
5796 5797
    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)
5798
    check_variable_and_dtype(
5799 5800 5801 5802 5803
        x,
        'x',
        ['float16', 'uint16', 'float32', 'float64', 'int32', 'int64'],
        op_type,
    )
5804
    check_variable_and_dtype(
5805 5806 5807 5808 5809
        y,
        'y',
        ['float16', 'uint16', 'float32', 'float64', 'int32', 'int64'],
        op_type,
    )
5810

S
sneaxiy 已提交
5811 5812
    axis = helper.kwargs.get('axis', -1)
    use_mkldnn = helper.kwargs.get('use_mkldnn', False)
S
sneaxiy 已提交
5813
    name = helper.kwargs.get('name', None)
5814
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
S
sneaxiy 已提交
5815

5816 5817 5818 5819 5820 5821
    helper.append_op(
        type=op_type,
        inputs={'X': x, 'Y': y},
        outputs={'Out': out},
        attrs={'axis': axis, 'use_mkldnn': use_mkldnn},
    )
S
sneaxiy 已提交
5822 5823 5824
    return helper.append_activation(out)


X
Xin Pan 已提交
5825
def elementwise_add(x, y, axis=-1, act=None, name=None):
5826
    """
5827

5828
    Examples:
5829

5830
        .. code-block:: python
5831

5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844
            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
5845

5846 5847 5848 5849
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5850

5851
            print(z_value) # [3., 8., 6.]
5852 5853


5854
        .. code-block:: python
5855

5856 5857 5858
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5859

5860 5861 5862 5863 5864 5865 5866 5867 5868 5869
            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
5870

5871 5872
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5873

5874 5875
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5876

5877
            print(z_value) # z.shape=[2,3,4,5]
5878 5879


5880
        ..  code-block:: python
5881

5882 5883 5884
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5885

5886 5887 5888 5889 5890 5891 5892 5893 5894 5895
            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
5896

5897 5898
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5899

5900 5901 5902
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
5903 5904

    """
J
Jiabin Yang 已提交
5905
    if _non_static_mode():
5906
        return _elementwise_op_in_dygraph(
5907 5908 5909 5910 5911
            x,
            y,
            axis=axis,
            act=act,
            op_name='elementwise_add',
5912 5913
            use_mkldnn=_global_flags()["FLAGS_use_mkldnn"],
        )
5914

S
sneaxiy 已提交
5915 5916 5917
    return _elementwise_op(LayerHelper('elementwise_add', **locals()))


5918
@deprecated(since="2.0.0", update_to="paddle.divide")
X
Xin Pan 已提交
5919
def elementwise_div(x, y, axis=-1, act=None, name=None):
5920
    """
5921

5922
    Examples:
5923

5924
        .. code-block:: python
5925

5926 5927 5928
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5929

5930 5931 5932 5933 5934 5935 5936 5937 5938 5939
            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
5940

5941 5942 5943 5944
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5945

5946
            print(z_value) # [2., 0.6, 2.]
5947 5948


5949
        .. code-block:: python
5950

5951 5952 5953
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5954

5955 5956 5957 5958 5959 5960 5961 5962 5963 5964
            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
5965

5966 5967
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5968

5969 5970
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5971

5972
            print(z_value) # z.shape=[2,3,4,5]
5973 5974


5975
        ..  code-block:: python
5976

5977 5978 5979
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5980

5981 5982 5983 5984 5985 5986 5987 5988 5989 5990
            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
5991

5992 5993
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5994

5995 5996 5997
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
5998 5999

    """
J
Jiabin Yang 已提交
6000
    if _non_static_mode():
6001 6002 6003
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_div'
        )
6004

S
sneaxiy 已提交
6005 6006 6007
    return _elementwise_op(LayerHelper('elementwise_div', **locals()))


X
Xin Pan 已提交
6008
def elementwise_sub(x, y, axis=-1, act=None, name=None):
6009
    """
6010

6011
    Examples:
6012

6013
        .. code-block:: python
6014

6015 6016 6017
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6018

6019 6020 6021 6022 6023 6024 6025 6026 6027 6028
            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
6029

6030 6031 6032 6033
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6034

6035
            print(z_value) # [1., -2., 2.]
6036 6037


6038
        .. code-block:: python
6039

6040 6041 6042
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6043

6044 6045 6046 6047 6048 6049 6050 6051 6052 6053
            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
6054

6055 6056
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6057

6058 6059
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6060

6061
            print(z_value) # z.shape=[2,3,4,5]
6062 6063


6064
        ..  code-block:: python
6065

6066 6067 6068
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6069

6070 6071 6072 6073 6074 6075 6076 6077 6078 6079
            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
6080

6081 6082
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6083

6084 6085 6086
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
6087 6088

    """
J
Jiabin Yang 已提交
6089
    if _non_static_mode():
6090 6091 6092
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_sub'
        )
6093

S
sneaxiy 已提交
6094 6095 6096
    return _elementwise_op(LayerHelper('elementwise_sub', **locals()))


6097
@deprecated(since="2.0.0", update_to="paddle.multiply")
X
Xin Pan 已提交
6098
def elementwise_mul(x, y, axis=-1, act=None, name=None):
6099
    """
6100

6101
    Examples:
6102

6103
        .. code-block:: python
6104

6105 6106 6107
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6108

6109 6110 6111 6112 6113 6114 6115 6116 6117 6118
            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
6119

6120 6121 6122 6123
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6124

6125
            print(z_value) # [2., 15., 8.]
6126 6127


6128
        .. code-block:: python
6129

6130 6131 6132
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6133

6134 6135 6136 6137 6138 6139 6140 6141 6142 6143
            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
6144

6145 6146
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6147

6148 6149
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6150

6151
            print(z_value) # z.shape=[2,3,4,5]
6152 6153


6154
        ..  code-block:: python
6155

6156 6157 6158
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6159

6160 6161 6162 6163 6164 6165 6166 6167 6168 6169
            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
6170

6171 6172
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6173

6174 6175 6176
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
6177

6178
    """
J
Jiabin Yang 已提交
6179
    if _non_static_mode():
6180 6181 6182
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_mul'
        )
6183

S
sneaxiy 已提交
6184 6185 6186 6187
    return _elementwise_op(LayerHelper('elementwise_mul', **locals()))


for func in [
6188 6189 6190 6191
    elementwise_add,
    elementwise_div,
    elementwise_sub,
    elementwise_mul,
6192 6193
]:
    op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
6194 6195

    # insert the c++ doc string on top of python doc string
6196 6197 6198 6199 6200
    func.__doc__ = (
        _generate_doc_string_(
            op_proto,
            additional_args_lines=[
                "axis (int32, optional): If X.dimension != Y.dimension, \
6201 6202
            Y.dimension must be a subsequence of x.dimension. \
            And axis is the start dimension index for broadcasting Y onto X. ",
6203
                "act (string, optional): Activation applied to the output. \
6204
            Default is None. Details: :ref:`api_guide_activations_en` ",
6205
                "name (string, optional): Name of the output. \
6206
            Default is None. It's used to print debug info for developers. Details: \
6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222
            :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__)
    )
6223

6224 6225 6226
    doc_list = func.__doc__.splitlines()

    for idx, val in enumerate(doc_list):
6227 6228 6229 6230 6231
        if (
            val.startswith("Warning: ")
            and val.endswith(" instead.")
            and "and will be removed in future versions." in val
        ):
6232 6233 6234 6235
            doc_list.insert(0, doc_list.pop(idx))
            func.__doc__ = "\n" + "\n".join(i for i in doc_list)
            break

6236
for func in []:
S
sneaxiy 已提交
6237 6238 6239 6240
    op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
    func.__doc__ = _generate_doc_string_(
        op_proto,
        additional_args_lines=[
S
sneaxiy 已提交
6241
            "act (basestring|None): Activation applied to the output.",
6242 6243 6244 6245 6246 6247
            "name (basestring|None): Name of the output.",
        ],
    )
    func.__doc__ = (
        func.__doc__
        + """
6248 6249 6250

Examples:
  .. code-block:: python
6251

6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281
    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)
6282 6283 6284 6285 6286 6287 6288 6289 6290 6291
    """
        % (
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
        )
    )
M
minqiyang 已提交
6292 6293


6294
def _logical_op(op_name, x, y, out=None, name=None, binary_op=True):
J
Jiabin Yang 已提交
6295
    if _non_static_mode():
6296
        op = getattr(_legacy_C_ops, op_name)
6297 6298 6299 6300
        if binary_op:
            return op(x, y)
        else:
            return op(x)
6301
    check_variable_and_dtype(
6302 6303
        x,
        "x",
6304
        ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
6305 6306
        op_name,
    )
6307
    if y is not None:
6308
        check_variable_and_dtype(
6309 6310
            y,
            "y",
6311
            ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
6312 6313
            op_name,
        )
6314
    if out is not None:
6315
        check_type(out, "out", Variable, op_name)
6316

M
minqiyang 已提交
6317 6318
    helper = LayerHelper(op_name, **locals())

6319 6320 6321
    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."
6322 6323
            % (op_name, x.dtype, y.dtype)
        )
M
minqiyang 已提交
6324 6325

    if out is None:
6326
        out = helper.create_variable_for_type_inference(dtype=x.dtype)
M
minqiyang 已提交
6327 6328

    if binary_op:
6329 6330 6331
        helper.append_op(
            type=op_name, inputs={"X": x, "Y": y}, outputs={"Out": out}
        )
M
minqiyang 已提交
6332 6333 6334 6335 6336 6337
    else:
        helper.append_op(type=op_name, inputs={"X": x}, outputs={"Out": out})

    return out


6338 6339 6340
@templatedoc()
def clip(x, min, max, name=None):
    """
6341
        :old_api: paddle.fluid.layers.clip
6342

6343 6344 6345 6346
    ${comment}

    Args:
        x(${x_type}): ${x_comment}
S
SunGaofeng 已提交
6347 6348
        min(float): ${min_comment}
        max(float): ${max_comment}
6349 6350
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
6351
                             For more information, please refer to :ref:`api_guide_Name`
6352 6353

    Returns:
S
SunGaofeng 已提交
6354 6355 6356 6357
        ${out_comment}

    Return Type:
        ${out_type}
6358 6359 6360 6361

    Examples:
        .. code-block:: python

S
SunGaofeng 已提交
6362
            import paddle.fluid as fluid
S
SunGaofeng 已提交
6363
            input = fluid.data(
6364 6365
                name='data', shape=[1], dtype='float32')
            reward = fluid.layers.clip(x=input, min=-1.0, max=1.0)
6366 6367 6368
    """

    helper = LayerHelper("clip", **locals())
6369
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'clip')
6370 6371

    if name is None:
6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385
        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},
    )
6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397

    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}
6398 6399 6400
        name(str, optional): For detailed information, please refer
            to :ref:`api_guide_Name`. Usually name is no need to set and
            None by default.
6401 6402

    Returns:
6403
        Tensor:
W
wangguanzhong 已提交
6404

6405
        out(${out_type}): ${out_comment}
6406

W
wangguanzhong 已提交
6407

6408 6409 6410
    Examples:
        .. code-block:: python

6411
            import paddle
6412
            import paddle.fluid as fluid
6413

6414 6415 6416
            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]]
6417 6418
    """

L
lyq 已提交
6419
    if in_dygraph_mode():
6420
        return _C_ops.clip_by_norm(x, max_norm)
J
Jiabin Yang 已提交
6421
    if _non_static_mode():
6422
        return _legacy_C_ops.clip_by_norm(x, 'max_norm', max_norm)
6423

6424
    helper = LayerHelper("clip_by_norm", **locals())
6425
    check_variable_and_dtype(x, 'X', ['float32', 'float16'], 'clip_by_norm')
6426
    check_type(max_norm, 'max_norm', (float), 'clip_by_norm')
6427 6428

    if name is None:
6429 6430 6431
        name = unique_name.generate_with_ignorable_key(
            ".".join([helper.name, 'tmp'])
        )
S
sneaxiy 已提交
6432

6433 6434 6435
    out = helper.create_variable(
        type=x.type, name=name, dtype=x.dtype, persistable=False
    )
6436

6437 6438 6439 6440 6441 6442
    helper.append_op(
        type="clip_by_norm",
        inputs={"X": x},
        attrs={"max_norm": max_norm},
        outputs={"Out": out},
    )
6443 6444

    return out
X
Xin Pan 已提交
6445 6446


6447
@deprecated(since="2.0.0", update_to="paddle.mean")
X
Xin Pan 已提交
6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458
@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}
6459 6460 6461 6462

    Examples:
        .. code-block:: python

6463
            import paddle
6464
            import paddle.fluid as fluid
6465 6466
            paddle.enable_static()

6467 6468
            input = fluid.layers.data(
                name='data', shape=[2, 3], dtype='float32')
6469
            mean = paddle.mean(input)
X
Xin Pan 已提交
6470
    """
6471

6472
    if _in_legacy_dygraph():
6473
        return _legacy_C_ops.mean(x)
6474
    if in_dygraph_mode():
6475
        return _C_ops.mean_all(x)
X
Xin Pan 已提交
6476 6477

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

6481 6482 6483
    helper.append_op(
        type="mean", inputs={"X": x}, attrs={}, outputs={"Out": out}
    )
X
Xin Pan 已提交
6484 6485 6486 6487

    return out


C
chengduo 已提交
6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498
@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}
6499 6500 6501 6502

    Examples:
        .. code-block:: python

6503
            import paddle.fluid as fluid
6504 6505 6506 6507 6508
            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 已提交
6509
    """
6510 6511 6512
    if in_dygraph_mode():
        return _C_ops.merge_selected_rows(x)

6513
    if _non_static_mode():
6514
        return _legacy_C_ops.merge_selected_rows(x)
C
chengduo 已提交
6515 6516 6517

    helper = LayerHelper("merge_selected_rows", **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
6518 6519 6520 6521 6522 6523
    helper.append_op(
        type="merge_selected_rows",
        inputs={"X": x},
        attrs={},
        outputs={"Out": out},
    )
C
chengduo 已提交
6524 6525 6526
    return out


X
Xin Pan 已提交
6527 6528
def mul(x, y, x_num_col_dims=1, y_num_col_dims=1, name=None):
    """
L
liu zhengxi 已提交
6529 6530 6531 6532 6533 6534 6535 6536
    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 已提交
6537 6538

    Args:
L
liu zhengxi 已提交
6539 6540
        x (Variable): The first input Tensor/LoDTensor of mul_op.
        y (Variable): The second input Tensor/LoDTensor of mul_op.
6541 6542 6543
        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 已提交
6544 6545

    Returns:
L
liu zhengxi 已提交
6546
        Variable(Tensor/LoDTensor): The output Tensor/LoDTensor of mul op.
6547 6548

    Examples:
L
liu zhengxi 已提交
6549
        ..  code-block:: python
6550

6551
            import paddle.fluid as fluid
6552 6553
            import paddle
            paddle.enable_static()
6554 6555 6556 6557 6558
            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)
6559

6560

X
Xin Pan 已提交
6561
    """
J
Jiabin Yang 已提交
6562
    if _non_static_mode():
6563 6564 6565 6566 6567 6568 6569 6570
        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 已提交
6571

6572 6573
    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 已提交
6574
    helper = LayerHelper("mul", **locals())
6575 6576
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'mul')
    check_variable_and_dtype(y, 'y', ['float16', 'float32', 'float64'], 'mul')
6577
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
X
Xin Pan 已提交
6578

6579 6580 6581
    helper.append_op(
        type="mul", inputs={"X": x, "Y": y}, attrs=attrs, outputs={"Out": out}
    )
X
Xin Pan 已提交
6582 6583 6584
    return out


M
minqiyang 已提交
6585 6586
def hash(input, hash_size, num_hash=1, name=None):
    """
6587

Z
zhupengyang 已提交
6588
    This OP hash the input to an integer less than the hash_size.
M
minqiyang 已提交
6589 6590
    The hash algorithm we used was xxHash - Extremely fast hash algorithm
    (https://github.com/Cyan4973/xxHash/tree/v0.6.5)
M
minqiyang 已提交
6591 6592

    Args:
Z
zhupengyang 已提交
6593 6594 6595 6596 6597 6598
        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 已提交
6599 6600

    Returns:
Z
zhupengyang 已提交
6601
       Variable: A LoDTensor with the same data type as input.
M
minqiyang 已提交
6602 6603

    Examples:
Z
zhupengyang 已提交
6604
        .. code-block:: python
H
haowang101779990 已提交
6605

6606
            import paddle.fluid as fluid
Z
zhupengyang 已提交
6607
            import numpy as np
6608 6609
            import paddle
            paddle.enable_static()
6610

Z
zhupengyang 已提交
6611
            place = fluid.core.CPUPlace()
6612

6613 6614
            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)
6615

Z
zhupengyang 已提交
6616 6617 6618 6619
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
            in1 = np.array([[1,2],[3,4]]).astype("int32")
            print(in1)
6620
            x_i = fluid.create_lod_tensor(in1, [[0, 2]], place)
Z
zhupengyang 已提交
6621 6622 6623 6624 6625 6626 6627 6628 6629 6630
            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 已提交
6631
    """
6632
    check_variable_and_dtype(input, 'input', ['int32', 'int64'], 'hash')
6633 6634
    check_type(hash_size, 'hash_size', int, 'hash')
    check_type(num_hash, 'num_hash', int, 'hash')
M
minqiyang 已提交
6635
    helper = LayerHelper('hash', **locals())
6636 6637 6638 6639 6640 6641 6642 6643 6644
    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 已提交
6645
    return out
G
gmcather 已提交
6646 6647


D
dengkaipeng 已提交
6648
@templatedoc()
6649 6650
def grid_sampler(x, grid, name=None):
    """
6651

6652
    This operation samples input X by using bilinear interpolation based on
T
tianshuo78520a 已提交
6653
    flow field grid, which is usually generated by :code:`affine_grid` . The grid of
K
Kaipeng Deng 已提交
6654 6655
    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 已提交
6656 6657
    (in width dimension) of input data x and y is indexing the 3rd
    dimension (in height dimension), finally results is the bilinear
6658
    interpolation value of 4 nearest corner points. The output tensor
K
Kaipeng Deng 已提交
6659
    shape will be [N, C, H, W].
6660

H
haowang101779990 已提交
6661
    .. code-block:: text
6662

H
haowang101779990 已提交
6663 6664
        Step 1:
        Get (x, y) grid coordinates and scale to [0, H-1/W-1].
6665

K
Kaipeng Deng 已提交
6666 6667 6668 6669
        .. code-block:: text

            grid_x = 0.5 * (grid[:, :, :, 0] + 1) * (W - 1)
            grid_y = 0.5 * (grid[:, :, :, 1] + 1) * (H - 1)
6670

H
haowang101779990 已提交
6671 6672 6673
        Step 2:
        Indices input data X with grid (x, y) in each [H, W] area, and bilinear
        interpolate point value by 4 nearest points.
6674

H
haowang101779990 已提交
6675 6676 6677 6678 6679 6680 6681 6682 6683
          wn ------- y_n ------- en
          |           |           |
          |          d_n          |
          |           |           |
         x_w --d_w-- grid--d_e-- x_e
          |           |           |
          |          d_s          |
          |           |           |
          ws ------- y_s ------- wn
6684

H
haowang101779990 已提交
6685 6686 6687 6688
        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
6689

H
haowang101779990 已提交
6690 6691 6692 6693
        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
6694

H
haowang101779990 已提交
6695 6696 6697 6698
        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
6699

H
haowang101779990 已提交
6700 6701
        output = wn * d_e * d_s + en * d_w * d_s
               + ws * d_e * d_n + es * d_w * d_n
D
dengkaipeng 已提交
6702 6703

    Args:
K
Kaipeng Deng 已提交
6704 6705 6706 6707 6708 6709 6710 6711 6712
        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 已提交
6713 6714

    Returns:
H
haowang101779990 已提交
6715
        Variable: Output of shape [N, C, H, W] data samples input X
K
Kaipeng Deng 已提交
6716 6717
                  using bilnear interpolation based on input grid.
                  The data type is same as input tensor.
6718

H
haowang101779990 已提交
6719 6720 6721 6722
    Examples:

        .. code-block:: python

K
Kaipeng Deng 已提交
6723
            import paddle.fluid as fluid
6724 6725
            import paddle.fluid as fluid
            import paddle
K
Kaipeng Deng 已提交
6726

6727
            paddle.enable_static()
K
Kaipeng Deng 已提交
6728 6729
            # use with affine_grid
            x = fluid.data(name='x', shape=[None, 10, 32, 32], dtype='float32')
K
Kaipeng Deng 已提交
6730 6731
            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 已提交
6732
            out = fluid.layers.grid_sampler(x=x, grid=grid)
6733

D
dengkaipeng 已提交
6734 6735 6736
    """
    helper = LayerHelper("grid_sampler", **locals())

6737
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'grid_sampler')
6738 6739 6740
    check_variable_and_dtype(
        grid, 'grid', ['float32', 'float64'], 'grid_sampler'
    )
D
dengkaipeng 已提交
6741 6742 6743 6744 6745 6746
    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")

6747
    out = helper.create_variable_for_type_inference(x.dtype)
D
dengkaipeng 已提交
6748 6749
    ipts = {'X': x, 'Grid': grid}

6750 6751
    attrs = {'use_cudnn': False} if core.is_compiled_with_rocm() else {}

6752 6753 6754
    helper.append_op(
        type='grid_sampler', inputs=ipts, outputs={'Output': out}, attrs=attrs
    )
6755 6756 6757
    return out


G
gmcather 已提交
6758
def log_loss(input, label, epsilon=1e-4, name=None):
6759
    r"""
6760

G
gmcather 已提交
6761 6762 6763 6764 6765 6766 6767
    **Negative Log Loss Layer**

    This layer accepts input predictions and target label and returns the
    negative log loss.

    .. math::

6768 6769
        Out = -label * \log{(input + \epsilon)}
              - (1 - label) * \log{(1 - input + \epsilon)}
G
gmcather 已提交
6770 6771

    Args:
6772
        input (Tensor|list):  A 2-D tensor with shape [N x 1], where N is the
G
gmcather 已提交
6773
                                batch size. This input is a probability computed
Y
Yibing Liu 已提交
6774
                                by the previous operator. Data type float32.
6775
        label (Tensor|list):  The ground truth which is a 2-D tensor with
6776
                                shape [N x 1], where N is the batch size.
Y
Yibing Liu 已提交
6777 6778
                                Data type float32.
        epsilon (float, optional): A small number for numerical stability. Default 1e-4.
6779
        name(str|None): For detailed information, please refer to
Y
Yibing Liu 已提交
6780
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
G
gmcather 已提交
6781 6782

    Returns:
6783
        Tensor, which shape is [N x 1], data type is float32.
G
gmcather 已提交
6784 6785 6786 6787

    Examples:
        .. code-block:: python

6788 6789 6790 6791 6792 6793
          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 已提交
6794
    """
6795
    return paddle.nn.functional.log_loss(input, label, epsilon, name)
G
gmcather 已提交
6796 6797


6798 6799 6800
def bilinear_tensor_product(
    x, y, size, act=None, name=None, param_attr=None, bias_attr=None
):
6801
    r"""
6802 6803
    :api_attr: Static Graph

Y
Yibing Liu 已提交
6804
    **Bilinear Tensor Product Layer**
Q
Qiao Longfei 已提交
6805

Q
Qiao Longfei 已提交
6806
    This layer performs bilinear tensor product on two inputs.
Q
Qiao Longfei 已提交
6807 6808 6809
    For example:

    .. math::
H
haowang101779990 已提交
6810
       out_{i} = x * W_{i} * {y^\mathrm{T}}, i=0,1,...,size-1
Q
Qiao Longfei 已提交
6811

Q
Qiao Longfei 已提交
6812
    In this formula:
6813 6814
      - :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 已提交
6815
      - :math:`W_{i}`: the i-th learned weight, shape is [M, N].
H
haowang101779990 已提交
6816
      - :math:`out_{i}`: the i-th element of out, shape is [batch_size, size].
Q
Qiao Longfei 已提交
6817 6818 6819
      - :math:`y^\mathrm{T}`: the transpose of :math:`y_{2}`.

    Args:
6820
        x (Variable): 2-D input tensor with shape [batch_size, M]. Data type
Y
Yibing Liu 已提交
6821
            is float32 or float64.
6822
        y (Variable): 2-D input tensor with shape [batch_size, N]. Data type
Y
Yibing Liu 已提交
6823
            should be same as **x**.
Q
Qiao Longfei 已提交
6824
        size (int): The dimension of this layer.
Y
Yibing Liu 已提交
6825
        act (str|None): Activation to be applied to the output of this layer. Default None.
6826
        name(str|None): For detailed information, please refer to
Y
Yibing Liu 已提交
6827
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
6828 6829
        param_attr (ParamAttr|None): To specify the weight parameter attribute.
            Default: None, which means the default weight parameter property is
Y
Yibing Liu 已提交
6830
            used. See usage for details in :ref:`api_fluid_ParamAttr` .
6831 6832
        bias_attr (ParamAttr|None): To specify the bias parameter attribute.
            Default: None, which means the default bias parameter property is
Y
Yibing Liu 已提交
6833
            used. See usage for details in :ref:`api_fluid_ParamAttr` .
Q
Qiao Longfei 已提交
6834
    Returns:
Y
Yibing Liu 已提交
6835
        Variable: A 2-D Tensor of shape [batch_size, size]. Data type is the same as input **x**.
Q
Qiao Longfei 已提交
6836 6837 6838 6839

    Examples:
        .. code-block:: python

6840 6841 6842 6843 6844
            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 已提交
6845 6846
    """
    helper = LayerHelper('bilinear_tensor_product', **locals())
Q
Qiao Longfei 已提交
6847
    dtype = helper.input_dtype('x')
Q
Qiao Longfei 已提交
6848 6849 6850

    param_shape = [size, x.shape[1], y.shape[1]]

6851 6852 6853
    w = helper.create_parameter(
        attr=helper.param_attr, shape=param_shape, dtype=dtype, is_bias=False
    )
6854
    out = helper.create_variable_for_type_inference(dtype=dtype)
Q
Qiao Longfei 已提交
6855 6856 6857 6858

    inputs = {"X": x, "Y": y, "Weight": w}
    if helper.bias_attr:
        bias_size = [1, size]
6859 6860 6861
        bias = helper.create_parameter(
            attr=helper.bias_attr, shape=bias_size, dtype=dtype, is_bias=True
        )
Q
Qiao Longfei 已提交
6862
        inputs["Bias"] = bias
6863 6864 6865
    helper.append_op(
        type="bilinear_tensor_product", inputs=inputs, outputs={"Out": out}
    )
Q
Qiao Longfei 已提交
6866 6867 6868

    # add activation
    return helper.append_activation(out)
C
chengduo 已提交
6869 6870 6871 6872 6873


@templatedoc()
def get_tensor_from_selected_rows(x, name=None):
    """
6874 6875 6876 6877 6878 6879 6880 6881 6882
    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]]

6883
        Output is LoDTensor:
6884 6885 6886 6887 6888 6889
           out.shape = [5, 2]
           out.data = [[1, 1],
                       [2, 2],
                       [2, 2],
                       [3, 3],
                       [6, 6]]
C
chengduo 已提交
6890 6891

    Args:
6892 6893 6894
        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 已提交
6895 6896

    Returns:
6897
        Variable: LoDTensor transformed from SelectedRows. The data type is same with input.
B
bdzhuxiaoning 已提交
6898 6899 6900

    Examples:
        .. code-block:: python
6901

B
bdzhuxiaoning 已提交
6902 6903 6904 6905
            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 已提交
6906 6907
    """

6908 6909 6910 6911 6912
    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 已提交
6913 6914
    helper = LayerHelper('get_tensor_from_selected_rows', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
6915 6916 6917 6918 6919 6920
    helper.append_op(
        type='get_tensor_from_selected_rows',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={},
    )
C
chengduo 已提交
6921
    return out
6922 6923


6924
@templatedoc()
6925
def temporal_shift(x, seg_num, shift_ratio=0.25, name=None, data_format="NCHW"):
6926
    """
6927

6928
    **Temporal Shift Operator**
6929

6930
    ${comment}
6931 6932

    Args:
6933
        x(Tensor): ${x_comment}
6934
        seg_num(int): ${seg_num_comment}
D
dengkaipeng 已提交
6935
        shift_ratio(float): ${shift_ratio_comment}
K
Kaipeng Deng 已提交
6936 6937 6938
        name(str, optional): For detailed information, please refer
                             to :ref:`api_guide_Name`. Usually name is no need to set and
                             None by default.
6939 6940
        data_format(str, optional): Data format that specifies the layout of input.
            It can be "NCHW" or "NHWC". Default: "NCHW".
6941 6942

    Returns:
6943
        out(Tensor): The temporal shifting result is a tensor with the
K
Kaipeng Deng 已提交
6944
        same shape and same data type as the input.
6945 6946 6947 6948 6949 6950 6951

    Raises:
        TypeError: seg_num must be int type.

    Examples:
        .. code-block:: python

6952 6953 6954 6955
            import paddle
            import paddle.nn.functional as F

            input = paddle.randn([6, 4, 2, 2])
6956
            out = F.temporal_shift(x=input, seg_num=2, shift_ratio=0.2)
6957
    """
6958 6959 6960
    return paddle.nn.functional.temporal_shift(
        x, seg_num, shift_ratio, name, data_format
    )
6961 6962


6963
class PyFuncRegistry:
S
sneaxiy 已提交
6964 6965 6966
    _register_funcs = []

    def __init__(self, func):
S
sneaxiy 已提交
6967
        if func is None or not callable(func):
S
sneaxiy 已提交
6968 6969 6970
            raise TypeError('func must be a Python function')

        self._func = func
M
minqiyang 已提交
6971
        # find named args using reflection
6972
        args = inspect.getfullargspec(self._func)
S
sneaxiy 已提交
6973 6974 6975 6976 6977 6978
        if len(args[0]) == 0 and args[1] is None and args[2] is None:
            # Function with no inputs
            self._named_args = None
        else:
            self._named_args = args[0]
        self._id = core._append_python_callable_object_and_return_id(self)
S
sneaxiy 已提交
6979 6980 6981
        '''
        Why record self here?

M
minqiyang 已提交
6982 6983
        1. For debug usage. Users can call
           :code:`py_func.registered_func(idx)` method
S
sneaxiy 已提交
6984
           to find the registered function corresponding
M
minqiyang 已提交
6985
           to :code:`idx`.
S
sneaxiy 已提交
6986

M
minqiyang 已提交
6987 6988
        2. For increasing reference count of self.
           It seems that to release Python object
S
sneaxiy 已提交
6989
           whose reference count is 1 would cause
M
minqiyang 已提交
6990
           segmentation fault error in C++ side.
S
sneaxiy 已提交
6991 6992
           May be lack of Python GC in C++ side?
        '''
S
sneaxiy 已提交
6993
        PyFuncRegistry._register_funcs.append(self)
S
sneaxiy 已提交
6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007

    @classmethod
    def registered_func(cls, idx):
        return cls._register_funcs[idx]._func

    @classmethod
    def registered_func_num(cls):
        return len(cls._register_funcs)

    @property
    def id(self):
        return self._id

    def __call__(self, *args):
S
sneaxiy 已提交
7008 7009 7010 7011 7012 7013 7014 7015 7016
        if self._named_args is None:
            func_ret = self._func()
        else:
            kwargs = dict()
            idx = 0
            for arg in self._named_args:
                kwargs[arg] = args[idx]
                idx += 1
            func_ret = self._func(*args[idx:], **kwargs)
S
sneaxiy 已提交
7017

S
sneaxiy 已提交
7018
        if not isinstance(func_ret, (list, tuple)):
7019
            func_ret = (func_ret,)
S
sneaxiy 已提交
7020 7021

        ret = []
S
sneaxiy 已提交
7022 7023 7024
        for each_ret in func_ret:
            if each_ret is None or isinstance(each_ret, core.LoDTensor):
                ret.append(each_ret)
S
sneaxiy 已提交
7025 7026
                continue

S
sneaxiy 已提交
7027 7028
            if not isinstance(each_ret, np.ndarray):
                each_ret = np.array(each_ret)
S
sneaxiy 已提交
7029

S
sneaxiy 已提交
7030 7031 7032
            tensor = core.LoDTensor()
            tensor.set(each_ret, core.CPUPlace())
            ret.append(tensor)
S
sneaxiy 已提交
7033

S
sneaxiy 已提交
7034
        return tuple(ret)
S
sneaxiy 已提交
7035 7036


7037
@static_only
S
sneaxiy 已提交
7038 7039 7040
@templatedoc()
def py_func(func, x, out, backward_func=None, skip_vars_in_backward_input=None):
    """
7041 7042
    :api_attr: Static Graph

7043 7044
    This OP is used to register customized Python OP to Paddle. The design
    principe of py_func is that Tensor and numpy array can be converted to each
7045 7046
    other easily. So you can use Python and numpy API to register a python OP.

7047 7048
    The forward function of the registered OP is ``func`` and the backward function
    of that is ``backward_func``. Paddle will call ``func`` at forward runtime and
7049
    call ``backward_func`` at backward runtime(if ``backward_func`` is not  None).
7050 7051
    ``x`` is the input of ``func``, whose type must be Tensor; ``out`` is
    the output of ``func``, whose type can be either Tensor or numpy array.
7052

7053
    The input of the backward function ``backward_func`` is ``x``, ``out`` and
7054 7055 7056
    the gradient of ``out``. If ``out`` have no gradient, the relevant input of
    ``backward_func`` is None. If ``x`` do not have a gradient, the user should
    return None in ``backward_func``.
7057

7058 7059
    The data type and shape of ``out`` should also be set correctly before this
    API is called, and the data type and shape of the gradient of ``out`` and
7060 7061 7062 7063 7064 7065 7066
    ``x`` will be inferred automatically.

    This API can also be used to debug the neural network by setting the ``func``
    as a function that only print variables.

    Args:
        func (callable): The forward function of the registered OP. When the network
7067 7068
            is running, the forward output ``out`` will be calculated according to this
            function and the forward input ``x``. In ``func`` , it's suggested that we
7069
            actively convert Tensor into a numpy array, so that we can use Python and
7070
            numpy API arbitrarily. If not, some operations of numpy may not be compatible.
7071 7072 7073 7074 7075 7076 7077
        x (Tensor|tuple(Tensor)|list[Tensor]): The input of the forward function ``func``.
            It can be Tensor|tuple(Tensor)|list[Tensor]. In addition, Multiple Tensor
            should be passed in the form of tuple(Tensor) or list[Tensor].
        out (T|tuple(T)|list[T]): The output of the forward function ``func``, it can be
            T|tuple(T)|list[T], where T can be either Tensor or numpy array. Since Paddle
            cannot automatically infer the shape and type of ``out``, you must create
            ``out`` in advance.
7078 7079 7080
        backward_func (callable, optional): The backward function of the registered OP.
            Its default value is None, which means there is no reverse calculation. If
            it is not None, ``backward_func`` is called to calculate the gradient of
7081
            ``x`` when the network is at backward runtime.
7082 7083
        skip_vars_in_backward_input (Tensor, optional): It's used to limit the input
            list of ``backward_func``, and it can be Tensor|tuple(Tensor)|list[Tensor].
7084
            It must belong to either ``x`` or ``out``. The default  value is None, which means
7085 7086
            that no tensors need to be removed from ``x`` and ``out``. If it is not None,
            these tensors will not be the input of ``backward_func``. This parameter is only
7087
            useful when ``backward_func`` is not None.
7088 7089

    Returns:
7090
        Tensor|tuple(Tensor)|list[Tensor]: The output ``out`` of the forward function ``func``.
S
sneaxiy 已提交
7091 7092

    Examples:
7093
        .. code-block:: python
7094

7095
            # example 1:
7096
            import paddle
7097
            import numpy as np
7098

7099 7100 7101
            paddle.enable_static()

            # Creates a forward function, Tensor can be input directly without
7102
            # being converted into numpy array.
7103 7104 7105
            def tanh(x):
                return np.tanh(x)

7106
            # Skip x in backward function and return the gradient of x
7107
            # Tensor must be actively converted to numpy array, otherwise,
7108
            # operations such as +/- can't be used.
7109 7110
            def tanh_grad(y, dy):
                return np.array(dy) * (1 - np.square(np.array(y)))
7111

7112
            # Creates a forward function for debugging running networks(print value)
7113 7114
            def debug_func(x):
                print(x)
7115

7116
            def create_tmp_var(name, dtype, shape):
7117
                return paddle.static.default_main_program().current_block().create_var(
7118
                    name=name, dtype=dtype, shape=shape)
7119 7120 7121

            def simple_net(img, label):
                hidden = img
7122
                for idx in range(4):
7123
                    hidden = paddle.static.nn.fc(hidden, size=200)
7124 7125 7126
                    new_hidden = create_tmp_var(name='hidden_{}'.format(idx),
                        dtype=hidden.dtype, shape=hidden.shape)

7127
                    # User-defined forward and backward
7128
                    hidden = paddle.static.py_func(func=tanh, x=hidden,
7129 7130 7131
                        out=new_hidden, backward_func=tanh_grad,
                        skip_vars_in_backward_input=hidden)

7132
                    # User-defined debug functions that print out the input Tensor
7133
                    paddle.static.py_func(func=debug_func, x=hidden, out=None)
7134

7135
                prediction = paddle.static.nn.fc(hidden, size=10, activation='softmax')
7136 7137 7138 7139
                ce_loss = paddle.nn.loss.CrossEntropyLoss()
                return ce_loss(prediction, label)

            x = paddle.static.data(name='x', shape=[1,4], dtype='float32')
7140
            y = paddle.static.data(name='y', shape=[1], dtype='int64')
7141 7142 7143 7144 7145
            res = simple_net(x, y)

            exe = paddle.static.Executor(paddle.CPUPlace())
            exe.run(paddle.static.default_startup_program())
            input1 = np.random.random(size=[1,4]).astype('float32')
7146
            input2 = np.random.randint(1, 10, size=[1], dtype='int64')
7147 7148 7149 7150 7151 7152
            out = exe.run(paddle.static.default_main_program(),
                          feed={'x':input1, 'y':input2},
                          fetch_list=[res.name])
            print(out)

        .. code-block:: python
7153

7154
            # example 2:
7155
            # This example shows how to turn Tensor into numpy array and
7156
            # use numpy API to register an Python OP
7157
            import paddle
7158 7159
            import numpy as np

7160 7161
            paddle.enable_static()

7162
            def element_wise_add(x, y):
7163
                # Tensor must be actively converted to numpy array, otherwise,
7164
                # numpy.shape can't be used.
7165
                x = np.array(x)
7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178
                y = np.array(y)

                if x.shape != y.shape:
                    raise AssertionError("the shape of inputs must be the same!")

                result = np.zeros(x.shape, dtype='int32')
                for i in range(len(x)):
                    for j in range(len(x[0])):
                        result[i][j] = x[i][j] + y[i][j]

                return result

            def create_tmp_var(name, dtype, shape):
7179
                return paddle.static.default_main_program().current_block().create_var(
7180 7181 7182
                            name=name, dtype=dtype, shape=shape)

            def py_func_demo():
7183 7184
                start_program = paddle.static.default_startup_program()
                main_program = paddle.static.default_main_program()
7185 7186

                # Input of the forward function
7187 7188
                x = paddle.static.data(name='x', shape=[2,3], dtype='int32')
                y = paddle.static.data(name='y', shape=[2,3], dtype='int32')
7189

7190 7191 7192 7193
                # Output of the forward function, name/dtype/shape must be specified
                output = create_tmp_var('output','int32', [3,1])

                # Multiple Variable should be passed in the form of tuple(Variale) or list[Variale]
7194
                paddle.static.py_func(func=element_wise_add, x=[x,y], out=output)
7195

7196
                exe=paddle.static.Executor(paddle.CPUPlace())
7197 7198 7199 7200 7201
                exe.run(start_program)

                # Feed numpy array to main_program
                input1 = np.random.randint(1, 10, size=[2,3], dtype='int32')
                input2 = np.random.randint(1, 10, size=[2,3], dtype='int32')
7202
                out = exe.run(main_program,
7203 7204 7205 7206 7207 7208 7209 7210 7211
                            feed={'x':input1, 'y':input2},
                            fetch_list=[output.name])
                print("{0} + {1} = {2}".format(input1, input2, out))

            py_func_demo()

            # Reference output:
            # [[5, 9, 9]   + [[7, 8, 4]  =  [array([[12, 17, 13]
            #  [7, 5, 2]]     [1, 3, 3]]            [8, 8, 5]], dtype=int32)]
S
sneaxiy 已提交
7212
    """
S
sneaxiy 已提交
7213
    helper = LayerHelper('py_func', **locals())
7214
    check_type(x, 'X', (list, tuple, Variable, type(None)), 'py_func')
S
sneaxiy 已提交
7215 7216 7217
    if x is None:
        x = []
    elif isinstance(x, Variable):
S
sneaxiy 已提交
7218
        x = [x]
7219 7220 7221
    elif isinstance(x, tuple):
        x = list(x)
    elif not isinstance(x, (list, tuple, Variable)):
S
sneaxiy 已提交
7222
        raise TypeError('Input must be Variable/list(Variable)/tuple(Variable)')
7223
    check_type(out, 'Out', (list, tuple, Variable, type(None)), 'py_func')
S
sneaxiy 已提交
7224 7225 7226
    if out is None:
        out_list = []
    elif isinstance(out, Variable):
S
sneaxiy 已提交
7227
        out_list = [out]
7228 7229
    elif isinstance(out, tuple):
        out_list = list(out)
7230 7231 7232
    elif isinstance(out, list):
        out_list = out
    else:
S
sneaxiy 已提交
7233
        raise TypeError(
7234 7235
            'Output must be Variable/list(Variable)/tuple(Variable)'
        )
S
sneaxiy 已提交
7236

S
sneaxiy 已提交
7237
    fwd_func_id = PyFuncRegistry(func).id
7238 7239 7240
    bwd_func_id = (
        PyFuncRegistry(backward_func).id if backward_func is not None else -1
    )
S
sneaxiy 已提交
7241 7242

    for each_out in out_list:
S
sneaxiy 已提交
7243 7244
        if len(each_out.shape) == 0:
            raise ValueError(
S
sneaxiy 已提交
7245 7246
                'Output shapes of py_func op should be provided by users manually'
            )
S
sneaxiy 已提交
7247

S
sneaxiy 已提交
7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259
    backward_skip_vars = set()
    if backward_func is not None and skip_vars_in_backward_input is not None:
        if isinstance(skip_vars_in_backward_input, Variable):
            skip_vars_in_backward_input = [skip_vars_in_backward_input]

        fwd_in_out = [v.name for v in x]
        fwd_in_out.extend([v.name for v in out_list])
        fwd_in_out = set(fwd_in_out)
        backward_skip_vars = set()
        for v in skip_vars_in_backward_input:
            if not v.name in fwd_in_out:
                raise ValueError(
7260 7261 7262 7263
                    'Variable {} is not found in forward inputs and outputs'.format(
                        v.name
                    )
                )
S
sneaxiy 已提交
7264
            backward_skip_vars.add(v.name)
S
sneaxiy 已提交
7265

7266 7267 7268 7269 7270 7271 7272 7273 7274 7275
    helper.append_op(
        type='py_func',
        inputs={'X': x},
        outputs={'Out': out_list},
        attrs={
            'forward_callable_id': fwd_func_id,
            'backward_callable_id': bwd_func_id,
            'backward_skip_vars': list(backward_skip_vars),
        },
    )
S
sneaxiy 已提交
7276
    return out
S
sneaxiy 已提交
7277 7278 7279


# For debug usage
S
sneaxiy 已提交
7280 7281 7282 7283
py_func.registered_func = PyFuncRegistry.registered_func
py_func.registered_func_num = PyFuncRegistry.registered_func_num


R
ruri 已提交
7284 7285 7286
def pixel_shuffle(x, upscale_factor):
    """

R
ruri 已提交
7287
    This op rearranges elements in a tensor of shape [N, C, H, W]
R
ruri 已提交
7288 7289 7290
    to a tensor of shape [N, C/r**2, H*r, W*r].
    This is useful for implementing efficient sub-pixel convolution
    with a stride of 1/r.
7291
    Please refer to the paper: `Real-Time Single Image and Video Super-Resolution
R
ruri 已提交
7292 7293 7294
    Using an Efficient Sub-Pixel Convolutional Neural Network <https://arxiv.org/abs/1609.05158v2>`_ .
    by Shi et. al (2016) for more details.

R
ruri 已提交
7295
    Parameters:
R
ruri 已提交
7296

R
ruri 已提交
7297 7298
        x(Variable): 4-D tensor, the data type should be float32 or float64.
        upscale_factor(int): factor to increase spatial resolution.
R
ruri 已提交
7299 7300

    Returns:
7301
        Out(Variable): Reshaped tensor according to the new dimension.
R
ruri 已提交
7302 7303 7304 7305 7306 7307 7308

    Raises:
        ValueError: If the square of upscale_factor cannot divide the channels of input.

    Examples:
        .. code-block:: python

7309 7310 7311 7312 7313 7314 7315 7316
            # declarative mode
            import paddle.fluid as fluid
            import numpy as np
            input = fluid.data(name="input", shape=[2,9,4,4])
            output = fluid.layers.pixel_shuffle(x=input, upscale_factor=3)
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
7317

7318 7319
            input_data = np.random.rand(2,9,4,4).astype("float32")
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
7320 7321 7322
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
7323

7324 7325
            # print(output.shape)
            # (2L, 1L, 12L, 12L)
R
ruri 已提交
7326 7327 7328

    """

R
ruri 已提交
7329
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'pixel_shuffle')
R
ruri 已提交
7330 7331 7332 7333 7334 7335 7336
    helper = LayerHelper("pixel_shuffle", **locals())

    out = helper.create_variable_for_type_inference(dtype=x.dtype)

    if not isinstance(upscale_factor, int):
        raise TypeError("upscale factor must be int type")

7337 7338 7339 7340 7341 7342
    helper.append_op(
        type="pixel_shuffle",
        inputs={"X": x},
        outputs={"Out": out},
        attrs={"upscale_factor": upscale_factor},
    )
R
ruri 已提交
7343 7344 7345
    return out


7346 7347 7348 7349 7350
def fsp_matrix(x, y):
    """

    **FSP matrix op**

7351
    This op is used to calculate the flow of solution procedure (FSP) matrix of two 4-D Tensor feature maps.
7352 7353 7354 7355 7356 7357 7358 7359 7360 7361 7362
    Given feature map x with shape [x_channel, h, w] and feature map y with shape
    [y_channel, h, w], we can get the fsp matrix of x and y in two steps:

    1. reshape x into matrix with shape [x_channel, h * w] and reshape and
       transpose y into matrix with shape [h * w, y_channel].
    2. multiply x and y to get fsp matrix with shape [x_channel, y_channel].

    The output is a batch of fsp matrices.

    Args:

7363 7364 7365
        x (Variable): A 4-D Tensor feature map with shape [batch_size, x_channel, height, width].
                      A Tensor with type float32, float64.
        y (Variable): A 4-D Tensor feature map with shape [batch_size, y_channel, height, width].
7366
                      The y_channel can be different with the x_channel of Input(X)
7367 7368
                      while the other dimensions must be the same with Input(X)'s. A Tensor with
                      type float32, float64.
7369 7370 7371 7372

    Returns:

        fsp matrix (Variable): The output of FSP op with shape [batch_size, x_channel, y_channel].
7373 7374
        The x_channel is the channel of x and the y_channel is the channel of y. A Tensor with
        type float32, float64.
7375 7376 7377 7378 7379

    Examples:

        .. code-block:: python

B
Bai Yifan 已提交
7380
            import paddle.fluid as fluid
B
Bai Yifan 已提交
7381
            data = fluid.data(name='data', shape=[None, 3, 32, 32])
B
Bai Yifan 已提交
7382 7383 7384 7385
            feature_map_0 = fluid.layers.conv2d(data, num_filters=2,
                                                filter_size=3)
            feature_map_1 = fluid.layers.conv2d(feature_map_0, num_filters=2,
                                                filter_size=1)
7386 7387 7388
            loss = fluid.layers.fsp_matrix(feature_map_0, feature_map_1)

    """
7389 7390
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'fsp_matrix')
    check_variable_and_dtype(y, 'y', ['float32', 'float64'], 'fsp_matrix')
7391
    helper = LayerHelper('fsp_matrix', **locals())
7392 7393 7394
    out = helper.create_variable_for_type_inference(
        dtype=helper.input_dtype(input_param_name='x')
    )
7395 7396
    helper.append_op(type='fsp', inputs={'X': x, 'Y': y}, outputs={'Out': out})
    return out
H
heqiaozhi 已提交
7397 7398 7399


def continuous_value_model(input, cvm, use_cvm=True):
7400
    r"""
H
fix doc  
heqiaozhi 已提交
7401

H
heqiaozhi 已提交
7402
    **continuous_value_model layers**
H
fix doc  
heqiaozhi 已提交
7403

Z
zhoushiyu 已提交
7404
    Now, this OP is used in CTR project to remove or dispose show and click value in :attr:`input`.
H
fix doc  
heqiaozhi 已提交
7405

Z
zhoushiyu 已提交
7406 7407
    :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 已提交
7408
    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 已提交
7409 7410
    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 已提交
7411

Z
zhoushiyu 已提交
7412 7413 7414 7415 7416 7417 7418
    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 已提交
7419

H
heqiaozhi 已提交
7420
    Returns:
H
fix doc  
heqiaozhi 已提交
7421

Z
zhoushiyu 已提交
7422 7423
        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 已提交
7424

H
heqiaozhi 已提交
7425
    Examples:
H
fix doc  
heqiaozhi 已提交
7426

H
heqiaozhi 已提交
7427
        .. code-block:: python
H
fix doc  
heqiaozhi 已提交
7428

7429
          import paddle.fluid as fluid
Z
zhoushiyu 已提交
7430 7431
          input = fluid.data(name="input", shape=[64, 1], dtype="int64")
          label = fluid.data(name="label", shape=[64, 1], dtype="int64")
H
heqiaozhi 已提交
7432 7433 7434 7435 7436 7437 7438 7439
          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 已提交
7440

H
heqiaozhi 已提交
7441 7442 7443
    """
    helper = LayerHelper('cvm', **locals())
    out = helper.create_variable(dtype=input.dtype)
7444 7445 7446 7447 7448 7449 7450 7451 7452
    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 已提交
7453
    return out
Z
zhoukunsheng 已提交
7454 7455 7456 7457 7458 7459 7460


def where(condition):
    """
    Return an int64 tensor with rank 2, specifying the coordinate of true element in `condition`.

    Args:
7461
        condition(Variable): A bool tensor with rank at least 1, the data type is bool.
Z
zhoukunsheng 已提交
7462 7463

    Returns:
7464
        Variable, the output data type is int64. : The tensor variable storing a 2-D tensor, which involves all coordinate.
Z
zhoukunsheng 已提交
7465 7466 7467 7468

    Examples:
        .. code-block:: python

7469
             import paddle.fluid as fluid
7470 7471 7472
             import paddle.fluid.layers as layers
             import numpy as np

Z
zhoukunsheng 已提交
7473
             # condition is a tensor [True, False, True]
7474 7475 7476
             condition = layers.assign(np.array([1, 0, 1], dtype='int32'))
             condition = layers.cast(condition, 'bool')
             out = layers.where(condition) # [[0], [2]]
Z
zhoukunsheng 已提交
7477 7478

             # condition is a tensor [[True, False], [False, True]]
7479 7480 7481
             condition = layers.assign(np.array([[1, 0], [0, 1]], dtype='int32'))
             condition = layers.cast(condition, 'bool')
             out = layers.where(condition) # [[0, 0], [1, 1]]
Z
zhoukunsheng 已提交
7482 7483

             # condition is a tensor [False, False, False]
7484 7485 7486 7487
             condition = layers.assign(np.array([0, 0, 0], dtype='int32'))
             condition = layers.cast(condition, 'bool')
             out = layers.where(condition) # [[]]

Z
zhoukunsheng 已提交
7488
    """
H
hong 已提交
7489 7490

    if in_dygraph_mode():
7491
        return _C_ops.nonzero(condition)
7492 7493
    if _in_legacy_dygraph():
        return _legacy_C_ops.where_index(condition)
7494

W
wanghuancoder 已提交
7495 7496
    helper = LayerHelper("where_index", **locals())

Z
zhoukunsheng 已提交
7497
    out = helper.create_variable_for_type_inference(
7498 7499 7500 7501 7502 7503 7504 7505
        dtype=core.VarDesc.VarType.INT64
    )

    helper.append_op(
        type='where_index',
        inputs={'Condition': condition},
        outputs={'Out': [out]},
    )
Z
zhoukunsheng 已提交
7506
    return out
Z
zhoukunsheng 已提交
7507 7508


W
WangXi 已提交
7509
@deprecated(since="2.0.0", update_to="paddle.sign")
Z
zhoukunsheng 已提交
7510
def sign(x):
7511
    r"""
7512
    This OP returns sign of every element in `x`: 1 for positive, -1 for negative and 0 for zero.
Z
zhoukunsheng 已提交
7513 7514

    Args:
7515 7516
        x(Variable|numpy.ndarray): The input variable could be N-D tensor or N-D numpy array, \
            the input data type is float32 or float64.
Z
zhoukunsheng 已提交
7517 7518

    Returns:
7519
        Variable, the output data type is the same as input data type. : The output sign tensor with identical shape to input :attr:`x`.
Z
zhoukunsheng 已提交
7520 7521 7522 7523

    Examples:
        .. code-block:: python

7524 7525 7526
          import paddle.fluid as fluid
          import numpy as np

7527
          # [1.0, 0.0, -1.0]
7528
          data = fluid.layers.sign(np.array([3.0, 0.0, -2.0], dtype='float32'))
Z
zhoukunsheng 已提交
7529 7530 7531
    """

    helper = LayerHelper("sign", **locals())
7532 7533 7534 7535
    check_type(x, 'x', (Variable, np.ndarray), 'sign')
    if isinstance(x, np.ndarray):
        x = assign(x)
    check_dtype(x.dtype, 'x', ['float16', 'float32', 'float64'], 'sign')
Z
zhoukunsheng 已提交
7536 7537 7538 7539 7540
    out = helper.create_variable_for_type_inference(dtype=x.dtype)

    helper.append_op(type='sign', inputs={'X': [x]}, outputs={'Out': [out]})

    return out
7541 7542


Z
zhoukunsheng 已提交
7543
def unique(x, dtype='int32'):
7544
    r"""
Z
zhoukunsheng 已提交
7545 7546 7547
    Return a unique tensor for `x` and an index tensor pointing to this unique tensor.

    Args:
Z
Zhang Ting 已提交
7548 7549
        x(Tensor): A 1-D input tensor, it's data type should be float32, float64, int32, int64.
        dtype(np.dtype|str, optional): The type of index tensor: int32, int64. Default: int32.
Z
zhoukunsheng 已提交
7550 7551 7552 7553 7554 7555 7556 7557 7558 7559

    Returns:
        tuple: (out, index). `out` is the unique tensor for `x`, with identical dtype to `x`, and \
            `index` is an index tensor pointing to `out`, by which user can recover the original `x` tensor.

    Examples:
        .. code-block:: python

             import numpy as np
             import paddle.fluid as fluid
W
wawltor 已提交
7560
             x = fluid.layers.assign(np.array([2, 3, 3, 1, 5, 3], dtype='int32'))
Z
zhoukunsheng 已提交
7561 7562 7563
             out, index = fluid.layers.unique(x) # out is [2, 3, 1, 5]; index is [0, 1, 1, 2, 3, 1]
    """

7564 7565 7566
    check_variable_and_dtype(
        x, "x", ['float32', 'float64', 'int32', 'int64'], "unique"
    )
Z
zhoukunsheng 已提交
7567 7568 7569 7570 7571 7572
    helper = LayerHelper("unique", **locals())

    out = helper.create_variable_for_type_inference(dtype=x.dtype)

    index = helper.create_variable_for_type_inference(dtype)

7573 7574 7575 7576 7577 7578
    helper.append_op(
        type='unique',
        inputs={'X': x},
        attrs={'dtype': convert_np_dtype_to_dtype_(dtype)},
        outputs={'Out': [out], 'Index': [index]},
    )
Z
zhoukunsheng 已提交
7579 7580 7581 7582

    return out, index


7583
def unique_with_counts(x, dtype='int32'):
7584
    r"""
T
tianshuo78520a 已提交
7585
    This OP return a unique tensor for `x` , and count tensor that the count of unique result in raw input, \
7586
    and an index tensor pointing to this unique tensor.
7587

7588
    **NOTICE**: This op support the variable type of Tensor only.
7589 7590

    Args:
7591
        x(Variable): A 1-D input tensor with input shape of :math:`[N]` , the input data type is float32, float64, int32, int64.
7592
        dtype(np.dtype|core.VarDesc.VarType|str): The type of count and index tensor, it could be int32, int64. Default value is int32.
7593

7594
    Returns:
7595 7596 7597
        tuple, the variable type in tuple is Tensor, the output :attr:`out` data type is the same as input :attr:`x`, \
        and data type of output :attr:`index` and :attr:`count` will be int32 or int64.: The :attr:`out` is unique tensor for input :attr:`x`,\
        the data shape is :math:`[K]`, the `K` may be different to the `N` in shape of :attr:`x`. :attr:`index` is an index tensor pointing\
T
tianshuo78520a 已提交
7598
        to :attr:`out`, the data shape is :math:`[N]` , the data shape is the same as input :attr:`x`. :attr:`count` is count of unique element in\
7599
        the :attr:`x`, the data shape is :math:`[K]`, the data shape is the same as output :attr:`out`.
7600 7601 7602 7603 7604 7605 7606 7607 7608

    Examples:
        .. code-block:: python

             import numpy as np
             import paddle.fluid as fluid
             x = fluid.layers.assign(np.array([2, 3, 3, 1, 5, 3], dtype='int32'))
             out, index, count = fluid.layers.unique_with_counts(x) # out is [2, 3, 1, 5]; index is [0, 1, 1, 2, 3, 1]
                                                        # count is [1, 3, 1, 1]
7609
            # x.shape=(6,) out.shape=(4,), index.shape=(6,), count.shape=(4,)
7610
    """
7611 7612 7613
    check_variable_and_dtype(
        x, "x", ['float32', 'float64', 'int32', 'int64'], "unique_with_counts"
    )
7614 7615
    if not (dtype == 'int32' or dtype == 'int64'):
        raise TypeError(
7616 7617
            "Op unique_with_counts, index dtype must be int32 or int64"
        )
7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631

    if x is None or len(x.shape) != 1:
        raise ValueError(
            "Op unique_with_counts, x must not be null and size of dim must be 1"
        )

    helper = LayerHelper("unique_with_counts", **locals())

    out = helper.create_variable_for_type_inference(dtype=x.dtype)

    index = helper.create_variable_for_type_inference(dtype)

    count = helper.create_variable_for_type_inference(dtype)

7632 7633 7634 7635 7636 7637
    helper.append_op(
        type='unique_with_counts',
        inputs={'X': x},
        attrs={'dtype': convert_np_dtype_to_dtype_(dtype)},
        outputs={'Out': [out], 'Index': [index], 'Count': [count]},
    )
7638 7639 7640 7641

    return out, index, count


7642
def unfold(x, kernel_sizes, strides=1, paddings=0, dilations=1, name=None):
7643
    r"""
7644

S
SunGaofeng 已提交
7645
    This op returns a col buffer of sliding local blocks of input x, also known
7646
    as im2col for batched 2D image tensors. For each block under the convolution filter,
T
tianshuo78520a 已提交
7647
    all element will be rearranged as a column. While the convolution filter sliding over
7648 7649
    the input feature map, a series of such columns will be formed.

S
SunGaofeng 已提交
7650
    For each input :math:`x` with shape [N, C, H, W], the output shape [N, Cout, Lout]
7651 7652 7653 7654
    can be calculated as following.

    .. math::

7655
        dkernel[0] &= dilations[0] \times (kernel\_sizes[0] - 1) + 1
7656

7657
        dkernel[1] &= dilations[1] \times (kernel\_sizes[1] - 1) + 1
7658

7659
        hout &= \frac{H + paddings[0] + paddings[2] - dkernel[0]}{strides[0]} + 1
7660

7661
        wout &= \frac{W + paddings[1] + paddings[3] - dkernel[1]}{strides[1]} + 1
7662

7663
        Cout &= C \times kernel\_sizes[0] \times kernel\_sizes[1]
7664

7665
        Lout &= hout \times wout
7666 7667


S
SunGaofeng 已提交
7668
    Parameters:
7669
        x(Tensor):              4-D Tensor, input tensor of format [N, C, H, W],
S
SunGaofeng 已提交
7670
                                  data type can be float32 or float64
7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682
        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 已提交
7683
        dilations(int|list):      the dilations of convolution kernel, should be
T
tianshuo78520a 已提交
7684
                                  [dilation_h, dilation_w], or an integer dilation treated as
7685
                                  [dilation, dilation]. For default, it will be [1, 1].
7686 7687
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
7688
                             For more information, please refer to :ref:`api_guide_Name`
7689

7690

7691
    Returns:
7692
        The tensor corresponding to the sliding local blocks.
7693 7694 7695
        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 已提交
7696 7697 7698
        The data type of output is the same as the input :math:`x`

    Return Type:
7699
        Tensor
7700 7701 7702 7703 7704

    Examples:

        .. code-block:: python

7705 7706 7707 7708 7709
            import paddle
            import paddle.nn.functional as F

            x = paddle.randn((100,3,224,224))
            y = F.unfold(x, [3, 3], 1, 1, 1)
7710 7711
    """

7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731
    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,
):
7732
    r"""
7733

7734
    Deformable ROI Pooling Layer
7735

7736
    Performs deformable region-of-interest pooling on inputs. As described
7737
    in `Deformable Convolutional Networks <https://arxiv.org/abs/1703.06211>`_, it will get offset for each bin after
7738
    roi pooling so that pooling at correct region. Batch_size will change to the number of region bounding boxes after deformable_roi_pooling.
7739

7740
    The operation has three steps:
7741

7742
    1. Dividing each region proposal into equal-sized sections with the pooled_width and pooled_height.
7743

7744 7745
    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.
7746

7747
    3. Sample several points in each bin to get average values as output.
7748 7749


7750 7751 7752 7753 7754 7755 7756 7757 7758
    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.
7759 7760 7761
        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.
7762 7763 7764 7765
        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.
7766
        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
7767
                          is k1 * k2 * (C + 1), which k1 and k2 are group width and height and C+1 is number of output
T
tianshuo78520a 已提交
7768
                          channels.) eg.(4, 6), which 4 is height of group and 6 is width of group. Default: [1, 1].
7769 7770 7771 7772 7773 7774 7775
        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 已提交
7776
                                   If value is True, input dimension should be output dimension * pooled_height * pooled_width. Default: False.
7777 7778 7779 7780
        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 已提交
7781 7782 7783 7784

    Examples:
      .. code-block:: python

7785 7786
        # position_sensitive=True
        import paddle.fluid as fluid
C
chengjuntao 已提交
7787
        input = fluid.data(name="input",
7788 7789
                           shape=[2, 192, 64, 64],
                           dtype='float32')
C
chengjuntao 已提交
7790 7791
        rois = fluid.data(name="rois",
                          shape=[-1, 4],
7792
                          dtype='float32',
C
chengjuntao 已提交
7793 7794
                          lod_level=1)
        trans = fluid.data(name="trans",
7795 7796 7797 7798 7799
                           shape=[2, 384, 64, 64],
                           dtype='float32')
        x = fluid.layers.deformable_roi_pooling(input=input,
                                                rois=rois,
                                                trans=trans,
C
chengjuntao 已提交
7800
                                                no_trans=False,
7801
                                                spatial_scale=1.0,
C
chengjuntao 已提交
7802 7803 7804 7805
                                                group_size=(1, 1),
                                                pooled_height=8,
                                                pooled_width=8,
                                                part_size=(8, 8),
7806
                                                sample_per_part=4,
C
chengjuntao 已提交
7807 7808
                                                trans_std=0.1,
                                                position_sensitive=True)
7809

7810
        # position_sensitive=False
7811
        import paddle.fluid as fluid
C
chengjuntao 已提交
7812
        input = fluid.data(name="input",
7813 7814
                           shape=[2, 192, 64, 64],
                           dtype='float32')
C
chengjuntao 已提交
7815 7816
        rois = fluid.data(name="rois",
                          shape=[-1, 4],
7817
                          dtype='float32',
C
chengjuntao 已提交
7818 7819
                          lod_level=1)
        trans = fluid.data(name="trans",
7820 7821 7822 7823 7824
                           shape=[2, 384, 64, 64],
                           dtype='float32')
        x = fluid.layers.deformable_roi_pooling(input=input,
                                                rois=rois,
                                                trans=trans,
C
chengjuntao 已提交
7825
                                                no_trans=False,
7826
                                                spatial_scale=1.0,
C
chengjuntao 已提交
7827 7828 7829 7830
                                                group_size=(1, 1),
                                                pooled_height=8,
                                                pooled_width=8,
                                                part_size=(8, 8),
7831
                                                sample_per_part=4,
C
chengjuntao 已提交
7832 7833
                                                trans_std=0.1,
                                                position_sensitive=False)
C
cjt222 已提交
7834 7835
    """

7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847
    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'
    )
7848
    if part_size is not None:
7849 7850 7851
        check_type(
            part_size, 'part_size', (list, tuple), 'deformable_roi_pooling'
        )
7852

C
cjt222 已提交
7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868
    input_channels = input.shape[1]
    if position_sensitive == False:
        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')
7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884
    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 已提交
7885
    return output
7886 7887


7888
@deprecated(since="2.0.0", update_to="paddle.shard_index")
7889 7890
def shard_index(input, index_num, nshards, shard_id, ignore_value=-1):
    """
L
lilong12 已提交
7891 7892 7893 7894 7895 7896 7897 7898 7899
    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).
7900 7901
    ::

7902
        shard_size = (index_num + nshards - 1) // nshards
7903

L
lilong12 已提交
7904 7905 7906
    For each value `v` in `input`, we reset it to a new value according to the
    following formula:
    ::
7907

L
lilong12 已提交
7908 7909 7910 7911
        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`.
7912 7913

    Args:
L
lilong12 已提交
7914 7915
        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`.
7916 7917 7918
        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.
7919 7920

    Returns:
L
lilong12 已提交
7921
        Tensor.
7922 7923 7924 7925

    Examples:
        .. code-block:: python

7926 7927 7928 7929 7930 7931 7932 7933
            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]]
7934
    """
H
hong 已提交
7935
    if in_dygraph_mode():
7936 7937 7938
        return _C_ops.shard_index(
            input, index_num, nshards, shard_id, ignore_value
        )
H
hong 已提交
7939

B
Baibaifan 已提交
7940
    check_variable_and_dtype(input, 'input', ['int64', 'int32'], 'shard_index')
7941 7942 7943
    op_type = 'shard_index'
    helper = LayerHelper(op_type, **locals())
    if shard_id < 0 or shard_id >= nshards:
7944 7945 7946
        raise ValueError(
            'The shard_id(%d) should be in [0, %d)' % (shard_id, nshards)
        )
7947 7948

    out = helper.create_variable_for_type_inference(dtype=input.dtype)
7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960
    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,
    )
7961
    return out
H
huangjun12 已提交
7962 7963 7964 7965


@templatedoc()
def hard_swish(x, threshold=6.0, scale=6.0, offset=3.0, name=None):
7966
    r"""
7967 7968 7969
    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 已提交
7970

7971
    The formula is as follows:
H
huangjun12 已提交
7972

7973
    .. math::
H
huangjun12 已提交
7974

7975
        out = \\frac{x * (min(max(0, x+offset), threshold))}{scale}
H
huangjun12 已提交
7976

7977 7978 7979 7980 7981 7982 7983 7984 7985
    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
7986 7987
        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`

7988 7989
    Returns:
        Variable: The output tensor with the same shape and data type as input.
7990 7991


7992
    Examples:
7993

7994
    .. code-block:: python
7995

7996
        import paddle.fluid as fluid
7997
        import paddle
7998
        import numpy as np
7999
        paddle.enable_static()
8000

8001
        DATATYPE='float32'
8002

8003
        x_data = np.array([i for i in range(1,5)]).reshape([1,1,4]).astype(DATATYPE)
8004

8005 8006
        x = fluid.data(name="x", shape=[None,1,4], dtype=DATATYPE)
        y = fluid.layers.hard_swish(x)
8007

8008 8009 8010 8011 8012
        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 已提交
8013
    """
J
Jiabin Yang 已提交
8014
    if _non_static_mode():
8015 8016 8017
        return _legacy_C_ops.hard_swish(
            x, 'threshold', threshold, 'scale', scale, 'offset', offset
        )
8018

8019 8020 8021
    check_variable_and_dtype(
        x, 'x', ['float16', 'float32', 'float64'], 'hard_swish'
    )
8022

H
huangjun12 已提交
8023 8024
    helper = LayerHelper('hard_swish', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
8025 8026 8027 8028 8029 8030
    helper.append_op(
        type='hard_swish',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'threshold': threshold, 'scale': scale, 'offset': offset},
    )
H
huangjun12 已提交
8031
    return out
R
ruri 已提交
8032 8033


K
Kaipeng Deng 已提交
8034 8035
@templatedoc()
def mish(x, threshold=20, name=None):
8036
    r"""
K
Kaipeng Deng 已提交
8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093
    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::

	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}

    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

        import paddle.fluid as fluid
        import numpy as np

        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.]]
    """
8094
    if in_dygraph_mode():
8095
        return _C_ops.mish(x, threshold)
8096
    if _in_legacy_dygraph():
8097
        return _legacy_C_ops.mish(x, 'threshold', threshold)
8098

K
Kaipeng Deng 已提交
8099 8100
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'mish')
    check_type(threshold, 'threshold', (float, int), 'mish')
8101 8102 8103 8104 8105
    assert (
        threshold > 0
    ), "threshold of mish should be greater than 0, " "but got {}".format(
        threshold
    )
K
Kaipeng Deng 已提交
8106 8107 8108

    helper = LayerHelper('mish', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
8109 8110 8111 8112 8113 8114
    helper.append_op(
        type='mish',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'threshold': threshold},
    )
K
Kaipeng Deng 已提交
8115 8116 8117
    return out


G
Guo Sheng 已提交
8118
def gather_tree(ids, parents):
8119
    r"""
G
Guo Sheng 已提交
8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143
    To be used after beam search. After beam search, we get selected ids at
    each time step and the corresponding parents in the search tree. Both ids
    and parents have the layout :attr:`[max_time, batch_size, beam_size]`. Then
    :attr:`gather_tree` is used to backtrace from the last time step and
    generate the full sequences by collecting selected ids.

    Here is an example:

    .. code-block:: text

            Given:
                ids = [[[2 2]
                        [6 1]]
                       [[3 9]
                        [6 1]]
                       [[0 1]
                        [9 0]]]
                parents = [[[0 0]
                            [1 1]]
                           [[1 0]
                            [1 0]]
                           [[0 0]
                            [0 1]]]

8144 8145
            Then:
                gather_tree(ids, parents)
G
Guo Sheng 已提交
8146 8147 8148 8149 8150 8151 8152 8153
                         = [[[2 2]
                             [1 6]]
                            [[3 3]
                             [6 1]]
                            [[0 1]
                             [9 0]]]

    Args:
L
liu zhengxi 已提交
8154
        ids(Tensor): A Tensor with shape :attr:`[length, batch_size, beam_size]`
G
Guo Sheng 已提交
8155 8156
            and data type :attr:`int32` or :attr:`int64`. It contains the selected
            ids of all time steps.
L
liu zhengxi 已提交
8157
        parents(Tensor): A Tensor with the same shape and data type as :attr:`ids`,
G
Guo Sheng 已提交
8158 8159 8160 8161
            It contains the parents corresponding to selected ids when searching
            among beams.

    Returns:
L
liu zhengxi 已提交
8162
            A Tensor with the same shape and data type as :attr:`ids`. \
G
Guo Sheng 已提交
8163 8164 8165 8166 8167 8168
            It contains the full sequences. The sequences are collected from \
            :attr:`ids` by backtracing according to :attr:`parents`.

    Examples:
        .. code-block:: python

L
liu zhengxi 已提交
8169 8170 8171 8172 8173 8174 8175 8176
            import paddle

            ids = paddle.to_tensor([[[2, 2], [6, 1]], [[3, 9], [6, 1]], [[0, 1], [9, 0]]])

            parents = paddle.to_tensor([[[0, 0], [1, 1]], [[1, 0], [1, 0]], [[0, 0], [0, 1]]])

            final_sequences = paddle.nn.functional.gather_tree(ids, parents)
            # [[[2, 2], [1, 6]], [[3, 3], [6, 1]], [[0, 1], [9, 0]]]
G
Guo Sheng 已提交
8177 8178

    """
8179
    return paddle.nn.functional.gather_tree(ids, parents)
G
Guo Sheng 已提交
8180 8181


8182
@deprecated(since="2.0.0", update_to="paddle.uniform")
8183
@templatedoc()
8184 8185 8186
def uniform_random(
    shape, dtype='float32', min=-1.0, max=1.0, seed=0, name=None
):
8187
    """
8188 8189
    This OP returns a Tensor filled with random values sampled from a uniform
    distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.
8190 8191 8192

    Examples:
    ::
8193

8194 8195
        Input:
          shape = [1, 2]
8196

8197 8198 8199 8200
        Output:
          result=[[0.8505902, 0.8397286]]

    Args:
8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213
        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
8214 8215
            use a seed generated by the system. Note that if seed is not 0,
            this operator will always generate the same random numbers every
8216
            time. Default is 0.
8217 8218 8219
        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`.
8220

8221
    Returns:
8222 8223
        Tensor: A Tensor filled with random values sampled from a uniform
        distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.
8224

8225
    Raises:
8226 8227
        TypeError: If ``shape`` is not list, tuple, Tensor.
        TypeError: If ``dtype`` is not float32, float64.
8228

8229 8230 8231
    Examples:
        .. code-block:: python

8232
            import paddle
8233
            import paddle.fluid as fluid
8234
            paddle.enable_static()
8235 8236

            # example 1:
8237
            # attr shape is a list which doesn't contain Tensor.
8238
            result_1 = fluid.layers.uniform_random(shape=[3, 4])
8239 8240 8241
            # [[ 0.84524226,  0.6921872,   0.56528175,  0.71690357],
            #  [-0.34646994, -0.45116323, -0.09902662, -0.11397249],
            #  [ 0.433519,    0.39483607, -0.8660099,   0.83664286]]
8242 8243

            # example 2:
8244 8245 8246
            # 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)
8247
            result_2 = fluid.layers.uniform_random(shape=[dim_1, dim_2])
8248 8249
            # [[-0.9951253,   0.30757582, 0.9899647 ],
            #  [ 0.5864527,   0.6607096,  -0.8886161 ]]
8250 8251

            # example 3:
8252
            # attr shape is a Tensor, the data type must be int64 or int32.
8253
            var_shape = fluid.data(name='var_shape', shape=[2], dtype="int64")
8254
            result_3 = fluid.layers.uniform_random(var_shape)
8255 8256 8257 8258
            # if var_shape's value is [2, 3]
            # result_3 is:
            # [[-0.8517412,  -0.4006908,   0.2551912 ],
            #  [ 0.3364414,   0.36278176, -0.16085452]]
8259

8260 8261 8262
    """
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
8263

8264 8265
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
8266
        return _C_ops.uniform(
8267 8268 8269 8270 8271 8272 8273
            shape,
            dtype,
            float(min),
            float(max),
            seed,
            _current_expected_place(),
        )
8274
    elif _in_legacy_dygraph():
8275
        shape = utils.convert_shape_to_list(shape)
8276 8277 8278 8279 8280 8281 8282 8283 8284 8285 8286 8287
        return _legacy_C_ops.uniform_random(
            'shape',
            shape,
            'min',
            float(min),
            'max',
            float(max),
            'seed',
            seed,
            'dtype',
            dtype,
        )
8288

8289
    check_type(shape, 'shape', (list, tuple, Variable), 'uniform_random/rand')
8290 8291 8292
    check_dtype(
        dtype, 'dtype', ('float32', 'float64', 'uint16'), 'uniform_random/rand'
    )
8293 8294
    check_type(min, 'min', (float, int, Variable), 'uniform_random/rand')
    check_type(max, 'max', (float, int, Variable), 'uniform_random/rand')
8295 8296

    inputs = dict()
8297
    attrs = {'seed': seed, 'min': min, 'max': max, 'dtype': dtype}
8298 8299 8300
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='uniform_random/rand'
    )
8301

8302
    helper = LayerHelper("uniform_random", **locals())
8303
    out = helper.create_variable_for_type_inference(dtype)
8304 8305 8306
    helper.append_op(
        type="uniform_random", inputs=inputs, attrs=attrs, outputs={"Out": out}
    )
8307
    utils.try_set_static_shape_tensor(out, shape)
8308
    return out
myq406450149's avatar
myq406450149 已提交
8309 8310 8311 8312 8313 8314 8315


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.
8316

myq406450149's avatar
myq406450149 已提交
8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341
        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()
8342 8343 8344
    check_dtype(
        dtype, 'unbind', ['float32', 'float64', 'int32', 'int64'], 'unbind'
    )
myq406450149's avatar
myq406450149 已提交
8345
    if not isinstance(axis, (int)):
8346 8347 8348
        raise TypeError(
            "The type of 'axis'  must be int, but received %s." % (type(axis))
        )
myq406450149's avatar
myq406450149 已提交
8349 8350 8351 8352 8353 8354 8355 8356 8357 8358
    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)
    ]

8359 8360 8361 8362 8363 8364
    helper.append_op(
        type="unbind",
        inputs={"X": input},
        outputs={"Out": outs},
        attrs={"axis": axis},
    )
myq406450149's avatar
myq406450149 已提交
8365
    return outs