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

127
OP_NAMEMAPPING = {
128 129 130 131 132 133 134 135
    '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 已提交
136
    'elementwise_mod': 'remainder',
137 138
}

Y
Yu Yang 已提交
139

140 141
def _get_reduce_dim(dim, input):
    """
142
    Internal function for reduce_sum, reduce_mean, reduce_prod.
143 144 145 146 147 148 149 150 151
    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(
152 153 154 155
                "The type of dim must be int, list, tuple or range, but received {}".format(
                    type(axis)
                )
            )
156 157 158 159 160 161 162 163 164 165
    if dim is None:
        dim = []
    if dim == [] or len(dim) == len(input.shape):
        reduce_all = True
    else:
        reduce_all = False

    return reduce_all, dim


166
@dygraph_only
167 168 169
def _elementwise_op_in_dygraph(
    x, y, axis=-1, act=None, use_mkldnn=False, op_name=None
):
170 171 172 173
    def is_inplace(op_name):
        return op_name[-1] == "_"

    if op_name not in OP_NAMEMAPPING.keys() or axis != -1:
174
        op = getattr(_legacy_C_ops, op_name)
175 176 177
        out = op(x, y, 'axis', axis, 'use_mkldnn', use_mkldnn)
    else:
        if in_dygraph_mode():
178 179
            op = getattr(
                _C_ops,
180 181
                OP_NAMEMAPPING[op_name] if not is_inplace(op_name) else op_name,
            )
182 183 184
            out = op(x, y)

        if _in_legacy_dygraph():
185
            op = getattr(_legacy_C_ops, op_name)
186
            out = op(x, y, 'axis', axis, 'use_mkldnn', use_mkldnn)
187 188 189 190 191 192 193 194 195 196 197 198 199 200
    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,
):
201
    r"""
202 203
    :api_attr: Static Graph

204
    **Fully Connected Layer**
Y
Yu Yang 已提交
205

206 207 208
    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,
209
    which represents a fully connected weight matrix from each input unit to
210 211 212 213
    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`
214
    is not None, a bias variable will be created and added to the output.
215
    Finally, if :attr:`act` is not None, it will be applied to the output as well.
C
caoying03 已提交
216

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

219 220 221 222
    .. math::

        Out = Act({XW + b})

223
    When the input is a list of Tensor(or LoDTensor):
224 225 226

    .. math::

227
        Out = Act({\sum_{i=0}^{N-1}X_iW_i + b})
228 229 230

    In the above equation:

231 232 233
    * :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 已提交
234
    * :math:`b`: The bias parameter created by this layer (if needed).
235
    * :math:`Act`: The activation function.
236
    * :math:`Out`: The output Tensor.
237 238 239

    .. code-block:: text

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

    Raises:
295
        ValueError: If dimensions of the input Tensor is less than 2.
296 297 298 299

    Examples:
        .. code-block:: python

300
          import paddle.fluid as fluid
301 302
          import paddle
          paddle.enable_static()
303
          # when input is single tensor
304
          data = fluid.data(name="data", shape=[-1, 32], dtype="float32")
305
          fc = fluid.layers.fc(input=data, size=1000, act="tanh")
306 307

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

330 331 332
        w = helper.create_parameter(
            attr=param_attr, shape=param_shape, dtype=dtype, is_bias=False
        )
X
Xin Pan 已提交
333
        tmp = helper.create_variable_for_type_inference(dtype)
334 335 336 337 338 339
        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},
        )
340 341 342 343
        mul_results.append(tmp)

    if len(mul_results) == 1:
        pre_bias = mul_results[0]
344
    else:
X
Xin Pan 已提交
345
        pre_bias = helper.create_variable_for_type_inference(dtype)
346 347 348 349 350 351
        helper.append_op(
            type="sum",
            inputs={"X": mul_results},
            outputs={"Out": pre_bias},
            attrs={"use_mkldnn": False},
        )
352 353 354 355
    # 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 已提交
356 357


T
tangwei12 已提交
358
@deprecated(since="2.0.0", update_to="paddle.nn.functional.embedding")
359 360 361 362 363 364 365 366 367
def embedding(
    input,
    size,
    is_sparse=False,
    is_distributed=False,
    padding_idx=None,
    param_attr=None,
    dtype='float32',
):
368
    r"""
369
    :api_attr: Static Graph
370

371 372 373 374 375 376 377 378 379 380 381 382
    **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.

383
    **Note:** The id in :attr:`input` must satisfy :math:`0 =< id < size[0]` ,
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
    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]],
401

402 403 404 405
                        [[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.
406

407
        Case 2:
408

409 410 411 412 413 414 415 416 417 418 419 420 421 422
        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 已提交
423 424

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

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

456 457
    Examples:
        .. code-block:: python
Y
Yu Yang 已提交
458

B
bdzhuxiaoning 已提交
459
          import paddle.fluid as fluid
460
          import numpy as np
461 462
          import paddle
          paddle.enable_static()
463

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

T
tianshuo78520a 已提交
466
          # example 1
467 468 469 470 471 472 473 474 475
          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)
476
          emb_2 = fluid.layers.embedding(input=data, size=(128, 100), param_attr=w_param_attrs, dtype='float32')
Y
Yu Yang 已提交
477 478 479
    """

    helper = LayerHelper('embedding', **locals())
480 481 482 483 484 485 486 487 488
    check_variable_and_dtype(
        input, 'input', ['int64'], 'fluid.layers.embedding'
    )
    check_dtype(
        dtype,
        'dtype',
        ['uint16', 'float16', 'float32', 'float64'],
        'fluid.layers.embedding',
    )
489 490 491 492 493 494 495 496 497

    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

498 499 500
    w = helper.create_parameter(
        attr=helper.param_attr, shape=size, dtype=dtype, is_bias=False
    )
X
Xin Pan 已提交
501
    tmp = helper.create_variable_for_type_inference(dtype)
502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519
    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 已提交
520 521 522
    return tmp


523 524 525 526 527 528 529 530 531 532 533
def _pull_sparse(
    input,
    size,
    table_id,
    accessor_class,
    name="embedding",
    ctr_label_name="",
    padding_id=0,
    dtype='float32',
    scale_sparse_grad=True,
):
534
    r"""
535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
    **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
580
        'is_distributed': True,
581 582
    }
    # this is only for compatible with embedding op
583 584 585 586 587 588 589 590 591
    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,
    )
592 593 594 595 596
    if len(outs) == 1:
        return outs[0]
    return outs


597 598 599 600 601 602 603 604 605 606 607
def _pull_sparse_v2(
    input,
    size,
    table_id,
    accessor_class,
    name="embedding",
    ctr_label_name="",
    padding_id=0,
    dtype='float32',
    scale_sparse_grad=True,
):
608
    r"""
609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
    **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
654
        'is_distributed': True,
655 656
    }
    # this is only for compatible with embedding op
657 658 659 660 661 662 663 664 665
    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,
    )
666
    if len(outs) == 1:
Y
yaoxuefeng 已提交
667 668 669 670
        return outs[0]
    return outs


671 672 673
def _pull_gpups_sparse(
    input, size, dtype='float32', is_distributed=False, is_sparse=False
):
Y
yaoxuefeng 已提交
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706
    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(
707 708 709
            "GpuPS only support float type embedding now, and your type is: "
            + dtype
        )
Y
yaoxuefeng 已提交
710 711 712 713 714 715
    helper.input_dtype()
    inputs = helper.multiple_input()
    outs = [
        helper.create_variable_for_type_inference(dtype)
        for i in range(len(inputs))
    ]
716 717 718 719 720 721 722 723 724 725 726 727 728
    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 已提交
729
    if len(outs) == 1:
730 731 732 733
        return outs[0]
    return outs


734 735 736
def _pull_box_sparse(
    input, size, dtype='float32', is_distributed=False, is_sparse=False
):
737
    r"""
H
hutuxian 已提交
738 739 740 741 742 743 744
    **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:
745
        input(Variable|list of Variable): Input is a Tensor<int64> Variable, which
H
hutuxian 已提交
746
            contains the IDs information.
747
        size(int): The embedding size parameter, which indicates the size of
H
hutuxian 已提交
748
            each embedding vector respectively.
749
        dtype(str): The dtype refers to the data type of output tensor. Only supports
H
hutuxian 已提交
750 751 752 753 754 755 756 757 758 759 760
	    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)
761
          emb = fluid.layers.pull_box_sparse(input=data, size=[11])
H
hutuxian 已提交
762 763 764 765
    """
    helper = LayerHelper('pull_box_sparse', **locals())
    if dtype != 'float32':
        raise ValueError(
766 767 768
            "BoxPS only support float type embedding now, and your type is: "
            + dtype
        )
H
hutuxian 已提交
769 770 771 772 773 774
    helper.input_dtype()
    inputs = helper.multiple_input()
    outs = [
        helper.create_variable_for_type_inference(dtype)
        for i in range(len(inputs))
    ]
775 776 777 778 779 780 781 782 783 784 785 786 787
    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 已提交
788 789 790 791 792
    if len(outs) == 1:
        return outs[0]
    return outs


Y
yuyang18 已提交
793
@templatedoc()
794
def linear_chain_crf(input, label, param_attr=None, length=None):
Y
yuyang18 已提交
795
    """
796 797
    :api_attr: Static Graph

Y
yuyang18 已提交
798 799 800 801 802
    Linear Chain CRF.

    ${comment}

    Args:
803
        input(${emission_type}): ${emission_comment}
Y
yuyang18 已提交
804
        label(${label_type}): ${label_comment}
805
        Length(${length_type}): ${length_comment}
806
        param_attr(ParamAttr): The attribute of the learnable parameter for transition parameter.
Y
yuyang18 已提交
807 808

    Returns:
D
dzhwinter 已提交
809 810
        output(${emission_exps_type}): ${emission_exps_comment} \n
        output(${transition_exps_type}): ${transition_exps_comment} \n
811
        output(${log_likelihood_type}): ${log_likelihood_comment} \n
Y
yuyang18 已提交
812

J
JesseyXujin 已提交
813 814 815
    Examples:
        .. code-block:: python

816 817
            import paddle.fluid as fluid
            import numpy as np
818 819
            import paddle
            paddle.enable_static()
820 821 822 823 824

            #define net structure, using LodTensor
            train_program = fluid.Program()
            startup_program = fluid.Program()
            with fluid.program_guard(train_program, startup_program):
825 826
                input_data = fluid.data(name='input_data', shape=[-1,10], dtype='float32')
                label = fluid.data(name='label', shape=[-1,1], dtype='int')
827 828 829 830 831 832
                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',
833
                    learning_rate=0.01))
834 835 836
            use_cuda = False
            place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
            exe = fluid.Executor(place)
837
            exe.run(startup_program)
838 839 840 841 842
            #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])
843
            print(loss)
844 845 846 847 848

            #define net structure, using padding
            train_program = fluid.Program()
            startup_program = fluid.Program()
            with fluid.program_guard(train_program, startup_program):
849 850 851
                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')
852 853 854 855 856 857
                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 已提交
858
                     name='crfw',
859 860 861 862 863 864
                     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 已提交
865

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

878 879 880
            #you can use find_var to get transition parameter.
            transition=np.array(fluid.global_scope().find_var('crfw').get_tensor())
            print(transition)
881

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

    return log_likelihood


W
wopeizl 已提交
927
@templatedoc()
928
def crf_decoding(input, param_attr, label=None, length=None):
W
wopeizl 已提交
929
    """
930
    :api_attr: Static Graph
931

W
wopeizl 已提交
932
    ${comment}
Y
yi.wu 已提交
933

W
wopeizl 已提交
934
    Args:
935
        input(Tensor): ${emission_comment}
Y
yi.wu 已提交
936

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

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

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

W
wopeizl 已提交
945
    Returns:
946
        Tensor: ${viterbi_path_comment}
Y
yi.wu 已提交
947

W
wopeizl 已提交
948 949
    Examples:
        .. code-block:: python
Y
yi.wu 已提交
950

951 952
           import paddle
           paddle.enable_static()
953 954 955

           # LoDTensor-based example
           num_labels = 10
956 957 958
           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)
959

960 961 962 963
           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"))
964 965 966

           # Common tensor example
           num_labels, max_len = 10, 20
967 968 969 970
           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,
971
                                      num_flatten_dims=2)
972

973 974 975 976
           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 已提交
977
    """
978 979 980
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'crf_decoding'
    )
W
wopeizl 已提交
981 982 983
    helper = LayerHelper('crf_decoding', **locals())
    transition = helper.get_parameter(param_attr.name)
    viterbi_path = helper.create_variable_for_type_inference(
984 985
        dtype=core.VarDesc.VarType.INT64
    )
986 987 988
    inputs = {"Emission": [input], "Transition": transition, "Label": label}
    if length:
        inputs['Length'] = length
989 990 991 992 993
    helper.append_op(
        type='crf_decoding',
        inputs=inputs,
        outputs={"ViterbiPath": [viterbi_path]},
    )
Y
Yu Yang 已提交
994

W
wopeizl 已提交
995
    return viterbi_path
Y
Yu Yang 已提交
996 997


998
@deprecated(since="2.0.0", update_to="paddle.nn.functional.dropout")
999 1000 1001 1002 1003 1004 1005 1006
def dropout(
    x,
    dropout_prob,
    is_test=None,
    seed=None,
    name=None,
    dropout_implementation="downgrade_in_infer",
):
1007
    """
1008

1009 1010 1011 1012
    Computes dropout.

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

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

1019
    Args:
L
lvmengsi 已提交
1020
        x (Variable): The input tensor variable. The data type is float16 or float32 or float64.
1021
        dropout_prob (float): Probability of setting units to zero.
1022
        is_test (bool): A flag indicating whether it is in test phrase or not.
1023
                        Default None, in dynamic graph, it use global tracer mode; in static graph, it means False.
1024 1025 1026
        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 已提交
1027
                    units will be dropped. DO NOT use a fixed seed in training.Default: None.
1028 1029
        name (str|None): A name for this layer(optional). If set None, the layer
                         will be named automatically.
H
haowang101779990 已提交
1030 1031
        dropout_implementation(string): ['downgrade_in_infer'(default)|'upscale_in_train']

P
phlrain 已提交
1032
                                        1. downgrade_in_infer(default), downgrade the outcome at inference
H
haowang101779990 已提交
1033 1034

                                           - train: out = input * mask
C
ceci3 已提交
1035
                                           - inference: out = input * (1.0 - dropout_prob)
H
haowang101779990 已提交
1036 1037 1038

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

H
haowang101779990 已提交
1041 1042
                                           - train: out = input * mask / ( 1.0 - dropout_prob )
                                           - inference: out = input
P
phlrain 已提交
1043

H
haowang101779990 已提交
1044 1045
                                           (mask is a tensor same shape with input, value is 0 or 1
                                           ratio of 0 is dropout_prob)
1046

M
minqiyang 已提交
1047

1048
    Returns:
L
lvmengsi 已提交
1049
        A Variable holding Tensor representing the dropout, has same shape and data type with `x`.
1050 1051

    Examples:
1052

1053 1054
        .. code-block:: python

1055
            import paddle
1056
            import paddle.fluid as fluid
1057

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

J
Jiabin Yang 已提交
1070
    if _non_static_mode():
1071 1072 1073
        if (
            seed is None or seed == 0
        ) and default_main_program().random_seed != 0:
1074
            seed = default_main_program().random_seed
1075 1076
        if is_test is None:
            is_test = not _dygraph_tracer()._train_mode
1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089
        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,
        )
1090
        return out
1091

W
wanghuancoder 已提交
1092 1093 1094
    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
1095 1096
        if isinstance(dropout_prob, Variable) and not dropout_prob.shape != [1]:
            raise TypeError(
1097 1098 1099 1100
                "Required dropout_prob.shape == [1] if type(dropout_prob) is Variable, but received dropout_prob.shape = {}".format(
                    dropout_prob.shape
                )
            )
W
wanghuancoder 已提交
1101 1102 1103 1104 1105 1106 1107 1108 1109
        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 已提交
1110
    helper = LayerHelper('dropout', **locals())
1111 1112 1113
    check_variable_and_dtype(
        x, 'x', ['float16', 'float32', 'float64'], 'dropout'
    )
1114

X
Xin Pan 已提交
1115 1116
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
    mask = helper.create_variable_for_type_inference(
1117 1118
        dtype=core.VarDesc.VarType.UINT8, stop_gradient=True
    )
C
chengduo 已提交
1119

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

1122 1123 1124 1125 1126 1127
    helper.append_op(
        type='dropout',
        inputs={'X': [x]},
        outputs={'Out': [out], 'Mask': [mask]},
        attrs=attrs,
    )
1128 1129 1130
    return out


1131
@deprecated(since="2.0.0", update_to="paddle.nn.functional.softmax")
1132
def softmax(input, use_cudnn=True, name=None, axis=-1):
1133
    r"""
1134
    This operator implements the softmax layer. The calculation process is as follows:
1135

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

1138 1139 1140 1141 1142 1143 1144
    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.
1145

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

1149 1150 1151 1152 1153
    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.
1154

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

1157
    .. math::
1158

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

1161
    Example:
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205

    .. 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],
1206
                         [0.72747516, 0.72747516, 0.72747516, 0.72747516]]]
1207

Q
qiaolongfei 已提交
1208
    Args:
N
Noel 已提交
1209
        input (Tensor): The input tensor. A multi-dimension ``Tensor`` with type float32 or float64.
1210
        use_cudnn (bool, optional): Use cudnn kernel or not, it is valid only when the cudnn \
G
GaoWei8 已提交
1211
            library is installed. To improve performance, set use_cudnn to True by default.
1212
        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 已提交
1213
            will be named automatically. Default: None.
1214
        axis (int, optional): The index of dimension to perform softmax calculations, it should
D
dengkaipeng 已提交
1215
            be in range :math:`[-1, rank - 1]`, while :math:`rank` is the rank of
N
Noel 已提交
1216
            input tensor. Default: -1. -1 means the last dimension.
Q
qiaolongfei 已提交
1217 1218

    Returns:
N
Noel 已提交
1219
        Tensor: ``Tensor`` indicates the output of softmax. The data type and shape are the same as ``input`` .
Q
qiaolongfei 已提交
1220 1221 1222 1223 1224

    Examples:

        .. code-block:: python

N
Noel 已提交
1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241
            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 已提交
1242 1243

    """
1244

H
hong 已提交
1245
    if in_dygraph_mode():
1246
        return _C_ops.softmax(input, axis)
H
hong 已提交
1247

J
Jiabin Yang 已提交
1248
    if _non_static_mode():
1249 1250 1251
        return _legacy_C_ops.softmax(
            input, 'axis', axis, 'use_cudnn', use_cudnn
        )
1252 1253 1254

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

1256
    helper = LayerHelper('softmax', **locals())
1257 1258 1259
    check_variable_and_dtype(
        input, 'input/x', ['float16', 'float32', 'float64'], 'softmax'
    )
1260

1261
    dtype = helper.input_dtype()
X
Xin Pan 已提交
1262
    softmax_out = helper.create_variable_for_type_inference(dtype)
1263 1264 1265 1266 1267 1268
    helper.append_op(
        type="softmax",
        inputs={"X": input},
        outputs={"Out": softmax_out},
        attrs=attrs,
    )
1269 1270 1271
    return softmax_out


1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286
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",
):
1287
    r"""
1288 1289
    :api_attr: Static Graph

C
chengduoZH 已提交
1290
    The convolution2D layer calculates the output based on the input, filter
T
tensor-tang 已提交
1291
    and strides, paddings, dilations, groups parameters. Input and
L
liym27 已提交
1292
    Output are in NCHW or NHWC format, where N is batch size, C is the number of
1293
    channels, H is the height of the feature, and W is the width of the feature.
T
tensor-tang 已提交
1294 1295 1296 1297 1298 1299
    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/>`_
1300
    for more details.
1301 1302 1303
    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 已提交
1304

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

C
chengduoZH 已提交
1307 1308
    .. math::

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

T
tensor-tang 已提交
1311
    Where:
C
chengduoZH 已提交
1312

L
liym27 已提交
1313
    * :math:`X`: Input value, a tensor with NCHW or NHWC format.
1314 1315 1316 1317
    * :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 已提交
1318
    * :math:`Out`: Output value, the shape of :math:`Out` and :math:`X` may be different.
C
chengduoZH 已提交
1319 1320 1321

    Example:

1322 1323
        - Input:

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

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

1328
        - Output:
T
tensor-tang 已提交
1329

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

C
chengduoZH 已提交
1332
        Where
1333 1334

        .. math::
C
chengduoZH 已提交
1335

W
weixing02 已提交
1336 1337
            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 已提交
1338 1339

    Args:
1340
        input (Tensor): The input is 4-D Tensor with shape [N, C, H, W], the data type
L
lvmengsi 已提交
1341
            of input is float16 or float32 or float64.
T
tensor-tang 已提交
1342
        num_filters(int): The number of filter. It is as same as the output
1343
            image channel.
1344 1345
        filter_size (int|tuple): The filter size. If filter_size
            is a tuple, it must contain two integers, (filter_size_height,
L
lvmengsi 已提交
1346 1347
            filter_size_width). Otherwise, filter_size_height = filter_size_width =\
            filter_size.
1348 1349
        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 已提交
1350 1351
            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 已提交
1352
            on both sides for each dimension.If `padding` is a string, either 'VALID' or
L
liym27 已提交
1353 1354
            '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
1355 1356
            `[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 已提交
1357
            [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right]]`.
L
liym27 已提交
1358 1359 1360
            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 已提交
1361
        dilation (int|tuple): The dilation size. It means the spacing between the kernel
1362 1363
            points. If dilation is a tuple, it must contain two integers, (dilation_height,
            dilation_width). Otherwise, dilation_height = dilation_width = dilation.
L
lvmengsi 已提交
1364
            Default: dilation = 1.
1365 1366 1367 1368
        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 已提交
1369 1370 1371 1372 1373
            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 已提交
1374
            and the :math:`std` is :math:`(\\frac{2.0 }{filter\_elem\_num})^{0.5}`. Default: None.
C
chengduo 已提交
1375 1376 1377 1378 1379
        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.
1380 1381
        use_cudnn (bool): Use cudnn kernel or not, it is valid only when the cudnn
            library is installed. Default: True
C
chengduo 已提交
1382 1383
        act (str): Activation type, if it is set to None, activation is not appended.
            Default: None
1384 1385
        name(str|None): For detailed information, please refer
           to :ref:`api_guide_Name`. Usually name is no need to set and
L
lvmengsi 已提交
1386
           None by default.
1387
        data_format (str, optional): Specify the data format of the input, and the data format of the output
1388
            will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`.
L
liym27 已提交
1389 1390
            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 已提交
1391 1392

    Returns:
1393 1394 1395
        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 已提交
1396
        and non-linearity activation result.
C
refine  
chengduoZH 已提交
1397

1398 1399 1400 1401 1402
    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".
1403
        ValueError: If `padding` is a tuple, but the element corresponding to the input's batch size is not 0
1404 1405 1406 1407 1408 1409 1410
            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 已提交
1411 1412 1413
    Examples:
        .. code-block:: python

1414 1415
          import paddle
          paddle.enable_static()
1416

1417 1418 1419
          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 已提交
1420 1421
    """

1422 1423 1424
    check_variable_and_dtype(
        input, 'input', ['float16', 'float32', 'float64'], 'conv2d'
    )
1425
    if len(input.shape) != 4:
1426 1427 1428 1429
        raise ValueError(
            "Input size should be 4, "
            "but received {}".format(len(input.shape))
        )
1430
    num_channels = input.shape[1]
L
liym27 已提交
1431
    if not isinstance(use_cudnn, bool):
1432 1433 1434 1435
        raise ValueError(
            "Attr(use_cudnn) should be True or False. Received "
            "Attr(use_cudnn): %s. " % str(use_cudnn)
        )
L
liym27 已提交
1436 1437 1438 1439

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

1443
    channel_last = data_format == "NHWC"
L
liym27 已提交
1444 1445 1446 1447
    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. "
1448 1449
            "Received: %s." % (str(input.shape), str(num_channels))
        )
C
chengduo 已提交
1450
    assert param_attr is not False, "param_attr should not be False here."
L
liym27 已提交
1451

1452 1453 1454
    if groups is None:
        num_filter_channels = num_channels
    elif groups <= 0:
1455 1456
        raise ValueError(
            "the groups of input must be greater than 0, "
1457 1458
            "but received the groups of input is {}".format(groups)
        )
1459 1460 1461 1462 1463
    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 {}"
1464 1465
                ", the groups is {}".format(num_channels, input.shape, groups)
            )
1466 1467
        num_filter_channels = num_channels // groups

1468
    l_type = 'conv2d'
1469 1470 1471 1472 1473
    if (
        num_channels == groups
        and num_filters % num_channels == 0
        and not use_cudnn
    ):
1474
        l_type = 'depthwise_conv2d'
1475

1476 1477 1478 1479 1480
    if (
        num_channels == groups
        and num_filters % num_channels == 0
        and core.is_compiled_with_rocm()
    ):
1481 1482
        l_type = 'depthwise_conv2d'

1483 1484
    # NPU only supports depthwise_conv2d when  "input_channel = output_channel = groups"
    if core.is_compiled_with_npu():
1485
        if num_channels == groups and num_channels == num_filters:
1486 1487 1488 1489
            l_type = 'depthwise_conv2d'
        else:
            l_type = 'conv2d'

1490 1491 1492
    helper = LayerHelper(l_type, **locals())
    dtype = helper.input_dtype()

C
chengduoZH 已提交
1493 1494
    filter_size = utils.convert_to_list(filter_size, 2, 'filter_size')
    stride = utils.convert_to_list(stride, 2, 'stride')
1495
    dilation = utils.convert_to_list(dilation, 2, 'dilation')
C
chengduoZH 已提交
1496

L
liym27 已提交
1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508
    # 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 "
1509 1510
                        "is not supported." % str(padding)
                    )
L
liym27 已提交
1511 1512 1513 1514 1515 1516
                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 "
1517 1518
                        "is not supported." % str(padding)
                    )
L
liym27 已提交
1519 1520 1521
                padding = padding[1:3]
                padding = [ele for a_list in padding for ele in a_list]
            padding = utils.convert_to_list(padding, 4, 'padding')
1522 1523 1524
            if utils._is_symmetric_padding(padding, 2):
                padding = [padding[0], padding[2]]

L
liym27 已提交
1525 1526 1527 1528 1529 1530 1531 1532 1533 1534
        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(
1535 1536 1537
                "Unknown padding: '%s'. It can only be 'SAME' or 'VALID'."
                % str(padding)
            )
L
liym27 已提交
1538 1539
        if padding == "VALID":
            padding_algorithm = "VALID"
1540
            padding = [0, 0]
L
liym27 已提交
1541 1542
        elif padding == "SAME":
            padding_algorithm = "SAME"
1543
            padding = [0, 0]
L
liym27 已提交
1544 1545

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

M
minqiyang 已提交
1547
    filter_shape = [num_filters, int(num_filter_channels)] + filter_size
Y
Yu Yang 已提交
1548 1549

    def _get_default_param_initializer():
C
chengduo 已提交
1550
        filter_elem_num = filter_size[0] * filter_size[1] * num_channels
1551 1552 1553 1554
        if filter_elem_num <= 0:
            raise ValueError(
                "Invalid filter number, excepted number is larger than 0, but"
                " received {}, please check the input shape and "
1555 1556 1557
                "filter size.".format(filter_elem_num)
            )
        std = (2.0 / filter_elem_num) ** 0.5
Y
Yu Yang 已提交
1558 1559 1560 1561 1562 1563
        return Normal(0.0, std, 0)

    filter_param = helper.create_parameter(
        attr=helper.param_attr,
        shape=filter_shape,
        dtype=dtype,
1564 1565
        default_initializer=_get_default_param_initializer(),
    )
Y
Yu Yang 已提交
1566

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

1569 1570 1571 1572 1573 1574
    if (
        core.is_compiled_with_cuda()
        and paddle.fluid.get_flags("FLAGS_conv2d_disable_cudnn")[
            "FLAGS_conv2d_disable_cudnn"
        ]
    ):
1575 1576
        use_cudnn = False

1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595
    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 已提交
1596

1597 1598 1599 1600
    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 已提交
1601 1602 1603 1604

    return helper.append_activation(pre_act)


F
fengjiayi 已提交
1605
@templatedoc()
1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618
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 已提交
1619
    """
1620

F
fengjiayi 已提交
1621
    ${comment}
1622 1623

    Args:
K
Kaipeng Deng 已提交
1624 1625 1626 1627 1628
        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 已提交
1629
        pool_size (int|list|tuple): The pool kernel size. If pool kernel size is a tuple or list,
J
JiabinYang 已提交
1630 1631
            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 已提交
1632
        pool_type: ${pooling_type_comment}
J
JiabinYang 已提交
1633 1634 1635
        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.
1636 1637 1638 1639 1640 1641 1642
        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 已提交
1643
            Otherwise, the pool padding size will be a square of an int.
1644 1645 1646
        global_pooling (bool): ${global_pooling_comment}
        use_cudnn (bool): ${use_cudnn_comment}
        ceil_mode (bool): ${ceil_mode_comment}
K
Kaipeng Deng 已提交
1647 1648 1649
        name(str, optional): For detailed information, please refer
                             to :ref:`api_guide_Name`. Usually name is no need to set and
                             None by default.
1650
        exclusive (bool): Whether to exclude padding points in average pooling
1651
                          mode, default is `true`.
1652
        data_format (string): The data format of the input and output data. An optional string from: `"NCHW"`, `"NHWC"`.
1653 1654
                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 已提交
1655

1656
    Returns:
K
Kaipeng Deng 已提交
1657
        Variable: The output tensor of pooling result. The data type is same as input tensor.
F
fengjiayi 已提交
1658 1659

    Raises:
1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671
        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 已提交
1672 1673 1674 1675 1676

    Examples:

        .. code-block:: python

1677
          import paddle.fluid as fluid
1678 1679 1680
          import paddle

          paddle.enable_static()
1681

K
Kaipeng Deng 已提交
1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706
          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)
1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724

          # 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 已提交
1725 1726 1727
    """
    if pool_type not in ["max", "avg"]:
        raise ValueError(
1728
            "Unknown Attr(pool_type): '%s'. It can only be 'max' or 'avg'.",
1729 1730
            str(pool_type),
        )
C
chengduoZH 已提交
1731

C
chengduoZH 已提交
1732 1733
    if global_pooling is False and pool_size == -1:
        raise ValueError(
1734
            "When Attr(global_pooling) is False, Attr(pool_size) must be passed "
1735 1736
            "and be a valid value. Received pool_size: %s." % str(pool_size)
        )
1737 1738

    if not isinstance(use_cudnn, bool):
1739 1740 1741 1742
        raise TypeError(
            "Attr(use_cudnn) should be True or False. Received "
            "Attr(use_cudnn): %s." % str(use_cudnn)
        )
1743 1744 1745 1746

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

C
chengduoZH 已提交
1750 1751 1752
    pool_size = utils.convert_to_list(pool_size, 2, 'pool_size')
    pool_stride = utils.convert_to_list(pool_stride, 2, 'pool_stride')

1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763
    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 "
1764 1765
                        "is not supported." % str(padding)
                    )
1766 1767 1768 1769 1770 1771
                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 "
1772 1773
                        "is not supported." % str(padding)
                    )
1774 1775 1776
                padding = padding[1:3]
                padding = [ele for a_list in padding for ele in a_list]
            padding = utils.convert_to_list(padding, 4, 'padding')
1777

1778 1779
            if utils._is_symmetric_padding(padding, 2):
                padding = [padding[0], padding[2]]
1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790
        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'."
1791 1792
                % str(pool_padding)
            )
1793 1794
        if pool_padding == "VALID":
            padding_algorithm = "VALID"
1795
            pool_padding = [0, 0]
1796 1797 1798
            if ceil_mode != False:
                raise ValueError(
                    "When Attr(pool_padding) is \"VALID\", Attr(ceil_mode) must be False. "
1799 1800
                    "Received ceil_mode: True."
                )
1801 1802
        elif pool_padding == "SAME":
            padding_algorithm = "SAME"
1803
            pool_padding = [0, 0]
1804 1805

    pool_padding = update_padding(pool_padding, data_format)
1806
    if in_dygraph_mode():
1807
        input = input._use_gpudnn(use_cudnn)
1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820
        return _C_ops.pool2d(
            input,
            pool_size,
            pool_stride,
            pool_padding,
            ceil_mode,
            exclusive,
            data_format,
            pool_type,
            global_pooling,
            False,
            padding_algorithm,
        )
1821 1822
    op_type = 'pool2d'
    helper = LayerHelper(op_type, **locals())
Y
Yu Yang 已提交
1823
    dtype = helper.input_dtype()
X
Xin Pan 已提交
1824
    pool_out = helper.create_variable_for_type_inference(dtype)
Y
Yu Yang 已提交
1825

1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843
    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,
        },
    )
1844 1845 1846 1847

    return pool_out


1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863
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,
):
1864
    r"""
1865 1866
    :api_attr: Static Graph

Q
qiaolongfei 已提交
1867 1868
    **Batch Normalization Layer**

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

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

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

Q
qiaolongfei 已提交
1876 1877 1878
    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 已提交
1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890

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

L
lvmengsi 已提交
1892
        moving\_mean = moving\_mean * momentum + mini-batch\_mean * (1. - momentum) \\\\
1893
        moving\_var = moving\_var * momentum + mini-batch\_var * (1. - momentum)
L
lvmengsi 已提交
1894

1895

L
lvmengsi 已提交
1896
    moving_mean is global mean and moving_var is global variance.
1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909

    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 已提交
1910
    Note:
1911
        if build_strategy.sync_batch_norm=True, the batch_norm in network will use
L
lvmengsi 已提交
1912
        sync_batch_norm automatically.
1913
        `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 已提交
1914

1915
    Args:
1916
        input(Tensor): The rank of input Tensor can be 2, 3, 4, 5. The data type
L
lvmengsi 已提交
1917
            is float16 or float32 or float64.
Q
qiaolongfei 已提交
1918
        act(string, Default None): Activation type, linear|relu|prelu|...
Q
qingqing01 已提交
1919 1920
        is_test (bool, Default False): A flag indicating whether it is in
            test phrase or not.
1921 1922
        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
1923
            shape [1] and data type as float32. The updated formula is:
Q
qingqing01 已提交
1924 1925 1926 1927 1928
            :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 已提交
1929 1930
        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
1931
	     will create ParamAttr as param_attr, the name of scale can be set in ParamAttr.
1932
	     If the Initializer of the param_attr is not set, the parameter is initialized
1933
	     with Xavier. Default: None.
C
chengduo 已提交
1934 1935
        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
1936 1937
	     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.
1938
	     Default: None.
1939
        data_layout (str, optional): Specify the data format of the input, and the data format of the output
K
Kaipeng Deng 已提交
1940 1941 1942
             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]`.
1943
        in_place(bool, Default False): Make the input and output of batch norm reuse memory.
1944 1945 1946 1947
        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
1948
            will save global mean with the string.
L
lvmengsi 已提交
1949
        moving_variance_name(str, Default None): The name of the moving_variance which store the global Variance.
1950
            If it is set to None, batch_norm will save global variance with a random name, otherwise, batch_norm
1951
            will save global variance with the string.
1952 1953
        do_model_average_for_mean_and_var(bool, Default True): Whether parameter mean and variance should do model
            average when model average is enabled.
1954 1955 1956 1957 1958
        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.
1959
    Returns:
1960
        A Tensor which is the result after applying batch normalization on the input,
1961
        has same shape and data type with input.
Q
qiaolongfei 已提交
1962 1963 1964 1965 1966

    Examples:

        .. code-block:: python

1967
            import paddle
1968

1969
            paddle.enable_static()
1970 1971 1972 1973 1974 1975 1976
            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 已提交
1977
    """
1978 1979 1980
    assert (
        bias_attr is not False
    ), "bias_attr should not be False in batch_norm."
Y
Yu Yang 已提交
1981 1982
    helper = LayerHelper('batch_norm', **locals())

1983 1984 1985
    check_variable_and_dtype(
        input, 'input', ['float16', 'float32', 'float64'], 'batch_norm'
    )
1986
    dtype = helper.input_dtype()
1987

W
Wu Yi 已提交
1988 1989 1990 1991
    # use fp32 for bn parameter
    if dtype == core.VarDesc.VarType.FP16:
        dtype = core.VarDesc.VarType.FP32

Y
Yu Yang 已提交
1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003
    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
2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023
    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,
    )
2024 2025
    mean.stop_gradient = True

2026 2027 2028 2029 2030 2031 2032 2033 2034 2035
    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,
    )
2036
    variance.stop_gradient = True
Y
Yu Yang 已提交
2037 2038 2039 2040

    # create output
    # mean and mean_out share the same memory
    mean_out = mean
2041
    # variance and variance_out share the same memory
Y
Yu Yang 已提交
2042
    variance_out = variance
2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054

    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:
2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070
            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,
            )
2071
        else:
2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085
            attrs_ = (
                'epsilon',
                epsilon,
                'is_test',
                is_test,
                'data_layout',
                data_layout,
                'use_mkldnn',
                False,
                'fuse_with_relu',
                False,
                'use_global_stats',
                use_global_stats,
            )
2086
        if inputs_has_MomemtumTensor:
2087
            batch_norm_out, _, _, _, _, _ = _legacy_C_ops.batch_norm(
2088 2089 2090 2091 2092 2093 2094 2095 2096 2097
                input,
                scale,
                bias,
                mean,
                variance,
                momentum,
                mean_out,
                variance_out,
                *attrs_,
            )
2098
        else:
2099
            batch_norm_out, _, _, _, _, _ = _legacy_C_ops.batch_norm(
2100 2101 2102 2103 2104 2105 2106 2107 2108 2109
                input,
                scale,
                bias,
                mean,
                variance,
                None,
                mean_out,
                variance_out,
                *attrs_,
            )
2110

2111 2112 2113
        return dygraph_utils._append_activation_in_dygraph(
            batch_norm_out, act=act, use_mkldnn=False
        )
2114

2115 2116 2117
    saved_mean = helper.create_variable_for_type_inference(
        dtype=dtype, stop_gradient=True
    )
X
Xin Pan 已提交
2118
    saved_variance = helper.create_variable_for_type_inference(
2119 2120
        dtype=dtype, stop_gradient=True
    )
2121
    reserve_space = None
2122
    if not is_test:
2123
        reserve_space = helper.create_variable_for_type_inference(
2124 2125
            dtype=helper.input_dtype(), stop_gradient=True
        )
2126

2127 2128 2129
    batch_norm_out = (
        input if in_place else helper.create_variable_for_type_inference(dtype)
    )
Y
Yu Yang 已提交
2130

2131 2132 2133 2134 2135
    inputs = {
        "X": input,
        "Scale": scale,
        "Bias": bias,
        "Mean": mean,
2136 2137
        "Variance": variance,
        "MeanOut": mean_out,
2138
        "VarianceOut": variance_out,
2139 2140 2141 2142 2143 2144 2145
    }
    attrs = {
        "epsilon": epsilon,
        "is_test": is_test,
        "data_layout": data_layout,
        "use_mkldnn": False,
        "fuse_with_relu": False,
2146
        "use_global_stats": use_global_stats,
2147 2148 2149 2150 2151
    }
    if isinstance(momentum, Variable):
        inputs['MomemtumTensor'] = momentum
    else:
        attrs['momentum'] = momentum
2152 2153 2154 2155 2156 2157

    outputs = {
        "Y": batch_norm_out,
        "MeanOut": mean_out,
        "VarianceOut": variance_out,
        "SavedMean": saved_mean,
2158
        "SavedVariance": saved_variance,
2159 2160 2161 2162
    }
    if reserve_space is not None:
        outputs["ReserveSpace"] = reserve_space

2163 2164 2165
    helper.append_op(
        type="batch_norm", inputs=inputs, outputs=outputs, attrs=attrs
    )
Y
Yu Yang 已提交
2166 2167 2168 2169

    return helper.append_activation(batch_norm_out)


Y
yuyang18 已提交
2170
@templatedoc()
2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181
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,
):
2182
    r"""
2183 2184
    :api_attr: Static Graph

2185 2186 2187 2188
    **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 已提交
2189 2190 2191

    The formula is as follows:

Y
yuyang18 已提交
2192
    ..  math::
G
guosheng 已提交
2193

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

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

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

2200 2201 2202 2203 2204
    - :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 已提交
2205

G
guosheng 已提交
2206
    Args:
2207
        input(Tensor): A multi-dimension ``Tensor`` , and the data type is float32 or float64.
2208 2209 2210 2211 2212
        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 已提交
2213
            dimensions from :attr:`begin_norm_axis` to :attr:`rank(input)`.
2214 2215 2216 2217
            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 已提交
2218 2219
            gain :math:`g`. If :attr:`scale` is False, :attr:`param_attr` is
            omitted. If :attr:`scale` is True and :attr:`param_attr` is None,
2220
            a default :code:`ParamAttr` would be added as scale. The
2221 2222
            :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 已提交
2223 2224
            bias :math:`b`. If :attr:`shift` is False, :attr:`bias_attr` is
            omitted. If :attr:`shift` is True and :attr:`param_attr` is None,
2225
            a default :code:`ParamAttr` would be added as bias. The
2226
            :attr:`bias_attr` is initialized as 0 if it is added. Default: None.
T
tianshuo78520a 已提交
2227
        act(str, optional): Activation to be applied to the output of layer normalization.
2228 2229
                  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 已提交
2230 2231

    Returns:
2232
        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 已提交
2233 2234 2235

    Examples:

2236 2237
        .. code-block:: python

2238 2239
            import paddle
            paddle.enable_static()
2240 2241 2242
            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 已提交
2243
    """
2244 2245 2246
    assert (
        _non_static_mode() is not True
    ), "please use LayerNorm instead of layer_norm in dygraph mode!"
G
guosheng 已提交
2247
    helper = LayerHelper('layer_norm', **locals())
2248 2249 2250
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'layer_norm'
    )
G
guosheng 已提交
2251 2252 2253 2254 2255 2256 2257
    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:
2258 2259 2260 2261 2262 2263 2264 2265 2266
        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 已提交
2267
        inputs['Scale'] = scale
2268 2269
    else:
        if param_attr:
T
tianshuo78520a 已提交
2270
            warnings.warn("param_attr is only available with scale is True.")
G
guosheng 已提交
2271
    if shift:
2272 2273 2274 2275 2276 2277
        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 已提交
2278
        inputs['Bias'] = bias
2279 2280
    else:
        if bias_attr:
T
tianshuo78520a 已提交
2281
            warnings.warn("bias_attr is only available with shift is True.")
G
guosheng 已提交
2282 2283

    # create output
2284 2285 2286 2287 2288 2289
    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 已提交
2290
    layer_norm_out = helper.create_variable_for_type_inference(dtype)
G
guosheng 已提交
2291

2292 2293 2294 2295 2296 2297 2298 2299 2300 2301
    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 已提交
2302 2303 2304 2305

    return helper.append_activation(layer_norm_out)


D
dengkaipeng 已提交
2306
@templatedoc()
2307
def spectral_norm(weight, dim=0, power_iters=1, eps=1e-12, name=None):
2308
    r"""
2309 2310
    :api_attr: Static Graph

D
dengkaipeng 已提交
2311 2312
    **Spectral Normalization Layer**

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

D
dengkaipeng 已提交
2318 2319 2320
    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 已提交
2321
    and W is the product result of remaining dimensions.
D
dengkaipeng 已提交
2322 2323

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

2328
    .. math::
D
dengkaipeng 已提交
2329 2330 2331 2332 2333 2334

        \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 已提交
2335
    Calculate :math:`\sigma(\mathbf{W})` and normalize weight values.
D
dengkaipeng 已提交
2336 2337 2338 2339

    .. math::

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

D
dengkaipeng 已提交
2341
        \mathbf{W} = \\frac{\mathbf{W}}{\sigma(\mathbf{W})}
2342

2343

D
dengkaipeng 已提交
2344 2345 2346
    Refer to `Spectral Normalization <https://arxiv.org/abs/1802.05957>`_ .

    Args:
C
Chen Long 已提交
2347
        weight(Tensor): ${weight_comment}
D
dengkaipeng 已提交
2348 2349 2350
        dim(int): ${dim_comment}
        power_iters(int): ${power_iters_comment}
        eps(float): ${eps_comment}
K
Kaipeng Deng 已提交
2351 2352 2353
        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 已提交
2354 2355

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

    Examples:
K
Kaipeng Deng 已提交
2360
       .. code-block:: python
D
dengkaipeng 已提交
2361

2362
            import paddle
K
Kaipeng Deng 已提交
2363

2364
            paddle.enable_static()
C
Chen Long 已提交
2365
            weight = paddle.static.data(name='weight', shape=[2, 8, 32, 32], dtype='float32')
2366
            x = paddle.static.nn.spectral_norm(weight=weight, dim=1, power_iters=2)
C
Chen Long 已提交
2367
            print(x.shape) # [2, 8, 32, 32]
D
dengkaipeng 已提交
2368 2369
    """
    helper = LayerHelper('spectral_norm', **locals())
2370 2371 2372
    check_variable_and_dtype(
        weight, 'weight', ['float32', 'float64'], 'spectral_norm'
    )
2373 2374 2375
    check_type(dim, 'dim', int, 'spectral_norm')
    check_type(power_iters, 'power_iters', int, 'spectral_norm')
    check_type(eps, 'eps', float, 'spectral_norm')
2376
    dtype = weight.dtype
D
dengkaipeng 已提交
2377 2378

    # create intput and parameters
2379
    input_shape = weight.shape
2380
    assert weight.numel() > 0, "Any dimension of input cannot be equal to 0."
2381 2382 2383 2384 2385
    assert dim < len(input_shape), (
        "The input `dim` should be less than the "
        "rank of `weight`, but received dim="
        "{}".format(dim)
    )
2386 2387 2388
    h = input_shape[dim]
    w = np.prod(input_shape) // h

2389 2390 2391 2392 2393 2394
    u = helper.create_parameter(
        attr=ParamAttr(),
        shape=[h],
        dtype=dtype,
        default_initializer=Normal(0.0, 1.0),
    )
2395
    u.stop_gradient = True
2396 2397 2398 2399 2400 2401
    v = helper.create_parameter(
        attr=ParamAttr(),
        shape=[w],
        dtype=dtype,
        default_initializer=Normal(0.0, 1.0),
    )
2402
    v.stop_gradient = True
D
dengkaipeng 已提交
2403

2404 2405 2406 2407 2408 2409 2410
    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 已提交
2411
    # create output
2412
    out = helper.create_variable(dtype=dtype)
D
Dun 已提交
2413

2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425
    helper.append_op(
        type="spectral_norm",
        inputs=inputs,
        outputs={
            "Out": out,
        },
        attrs={
            "dim": dim,
            "power_iters": power_iters,
            "eps": eps,
        },
    )
D
Dun 已提交
2426

2427
    return out
D
Dun 已提交
2428 2429


C
caoying03 已提交
2430
def reduce_sum(input, dim=None, keep_dim=False, name=None):
G
guosheng 已提交
2431
    """
2432

Y
yangyaming 已提交
2433
    Computes the sum of tensor elements over the given dimension.
G
guosheng 已提交
2434 2435

    Args:
2436 2437 2438
        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 已提交
2439 2440
            :attr:`None`, sum all elements of :attr:`input` and return a
            Tensor variable with a single element, otherwise must be in the
W
whs 已提交
2441 2442
            range :math:`[-rank(input), rank(input))`. If :math:`dim[i] < 0`,
            the dimension to reduce is :math:`rank + dim[i]`.
2443
        keep_dim (bool, optional): Whether to reserve the reduced dimension in the
Y
yangyaming 已提交
2444
            output Tensor. The result tensor will have one fewer dimension
2445 2446 2447 2448
            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 已提交
2449 2450

    Returns:
2451 2452
        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 已提交
2453

2454 2455
    Raises:
        TypeError, if out data type is different with the input data type.
2456

G
guosheng 已提交
2457 2458 2459
    Examples:
        .. code-block:: python

2460
            import paddle.fluid as fluid
2461 2462
            import paddle
            paddle.enable_static()
G
guosheng 已提交
2463 2464 2465
            # 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 已提交
2466
            # Each example is followed by the corresponding output tensor.
2467
            x = fluid.data(name='x', shape=[2, 4], dtype='float32')
G
guosheng 已提交
2468 2469 2470 2471
            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 已提交
2472

2473
            # y is a Tensor variable with shape [2, 2, 2] and elements as below:
W
whs 已提交
2474 2475
            #      [[[1, 2], [3, 4]],
            #      [[5, 6], [7, 8]]]
Q
qiaolongfei 已提交
2476
            # Each example is followed by the corresponding output tensor.
2477
            y = fluid.data(name='y', shape=[2, 2, 2], dtype='float32')
2478 2479
            fluid.layers.reduce_sum(y, dim=[1, 2]) # [10, 26]
            fluid.layers.reduce_sum(y, dim=[0, 1]) # [16, 20]
W
whs 已提交
2480

G
guosheng 已提交
2481
    """
2482 2483
    reduce_all, dim = _get_reduce_dim(dim, input)

2484
    if in_dygraph_mode():
2485
        return _C_ops.sum(input, dim, None, keep_dim)
2486
    elif _in_legacy_dygraph():
2487 2488 2489
        return _legacy_C_ops.reduce_sum(
            input, 'dim', dim, 'keep_dim', keep_dim, 'reduce_all', reduce_all
        )
2490
    attrs = {'dim': dim, 'keep_dim': keep_dim, 'reduce_all': reduce_all}
2491
    check_variable_and_dtype(
2492 2493 2494 2495 2496
        input,
        'input',
        ['float16', 'float32', 'float64', 'int32', 'int64'],
        'reduce_sum',
    )
2497
    helper = LayerHelper('reduce_sum', **locals())
X
Xin Pan 已提交
2498
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
2499 2500 2501 2502 2503 2504
    helper.append_op(
        type='reduce_sum',
        inputs={'X': input},
        outputs={'Out': out},
        attrs=attrs,
    )
G
guosheng 已提交
2505
    return out
G
guosheng 已提交
2506 2507


Z
zhoukunsheng 已提交
2508 2509
def reduce_all(input, dim=None, keep_dim=False, name=None):
    """
2510

2511
    This OP computes the ``logical and`` of tensor elements over the given dimension, and output the result.
Z
zhoukunsheng 已提交
2512 2513

    Args:
2514
        input (Tensor): the input tensor, it's data type should be `bool`.
2515
        dim (list|int|optional): The dimension along which the logical and is computed.
Z
zhoukunsheng 已提交
2516 2517 2518
            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))`.
2519
            If :math:`dim[i] < 0`, the dimension to reduce is :math:`rank + dim[i]`. The default value is None.
Z
zhoukunsheng 已提交
2520 2521
        keep_dim (bool): Whether to reserve the reduced dimension in the
            output Tensor. The result tensor will have one fewer dimension
2522
            than the :attr:`input` unless :attr:`keep_dim` is true. The default value is False.
Z
zhoukunsheng 已提交
2523
        name(str|None): A name for this layer(optional). If set None, the layer
2524
                       will be named automatically. The default value is None.
Z
zhoukunsheng 已提交
2525

2526
    Returns:
2527
        Tensor, the output data type is bool. : The reduced tensor variable with ``logical and`` in given dims.
Z
zhoukunsheng 已提交
2528 2529 2530

    Examples:
        .. code-block:: python
2531

2532
            import paddle
2533
            import paddle.fluid as fluid
2534 2535 2536
            import paddle.fluid.layers as layers
            import numpy as np

Z
zhoukunsheng 已提交
2537 2538 2539
            # x is a bool Tensor variable with following elements:
            #    [[True, False]
            #     [True, True]]
2540 2541
            x = fluid.layers.assign(np.array([[1, 0], [1, 1]], dtype='int32'))
            x = fluid.layers.cast(x, 'bool')
2542

2543 2544 2545
            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]
2546 2547
            # keep_dim=False, x.shape=(2,2), out.shape=(2,)

2548
            out = fluid.layers.reduce_all(x, dim=1, keep_dim=True)  # [[False], [True]]
2549
            # keep_dim=True, x.shape=(2,2), out.shape=(2,1)
Z
zhoukunsheng 已提交
2550 2551

    """
2552 2553
    if dim is not None and not isinstance(dim, list):
        dim = [dim]
2554 2555

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

2558
    check_variable_and_dtype(input, 'input', ('bool'), 'reduce_all')
Z
zhoukunsheng 已提交
2559 2560
    helper = LayerHelper('reduce_all', **locals())
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
2561 2562 2563 2564 2565
    helper.append_op(
        type='reduce_all',
        inputs={'X': input},
        outputs={'Out': out},
        attrs={
2566
            'dim': dim if dim is not None and dim != [] else [0],
2567 2568
            'keep_dim': keep_dim,
            'reduce_all': True
2569
            if dim is None or dim == [] or len(dim) == len(input.shape)
2570 2571 2572
            else False,
        },
    )
Z
zhoukunsheng 已提交
2573 2574 2575 2576 2577
    return out


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

    Args:
2581
        input (Tensor): the input tensor, it's data type should be `bool`.
2582 2583
        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 已提交
2584 2585
            :attr:`input` and return a Tensor variable with a single element,
            otherwise must be in the range :math:`[-rank(input), rank(input))`.
2586
            If :math:`dim[i] < 0`, the dimension to reduce is :math:`rank + dim[i]`. The default value is None.
Z
zhoukunsheng 已提交
2587 2588
        keep_dim (bool): Whether to reserve the reduced dimension in the
            output Tensor. The result tensor will have one fewer dimension
2589
            than the :attr:`input` unless :attr:`keep_dim` is true. The default value is False.
2590
        name (str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.
Z
zhoukunsheng 已提交
2591

2592
    Returns:
2593
        Tensor, the output data type is bool. : The reduced tensor variable with ``logical or`` in given dims.
Z
zhoukunsheng 已提交
2594 2595 2596

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

2598
            import paddle
2599
            import paddle.fluid as fluid
2600 2601 2602
            import paddle.fluid.layers as layers
            import numpy as np

Z
zhoukunsheng 已提交
2603 2604 2605
            # x is a bool Tensor variable with following elements:
            #    [[True, False]
            #     [False, False]]
2606 2607
            x = fluid.layers.assign(np.array([[1, 0], [0, 0]], dtype='int32'))
            x = fluid.layers.cast(x, 'bool')
2608

2609 2610 2611
            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]
2612 2613
            # keep_dim=False, x.shape=(2,2), out.shape=(2,)

2614
            out = fluid.layers.reduce_any(x, dim=1,
Z
zhoukunsheng 已提交
2615
                                     keep_dim=True)  # [[True], [False]]
2616
            # keep_dim=True, x.shape=(2,2), out.shape=(2,1)
Z
zhoukunsheng 已提交
2617 2618

    """
2619
    check_variable_and_dtype(input, 'input', ('bool'), 'reduce_any')
Z
zhoukunsheng 已提交
2620 2621 2622 2623
    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]
2624 2625 2626 2627 2628
    helper.append_op(
        type='reduce_any',
        inputs={'X': input},
        outputs={'Out': out},
        attrs={
2629
            'dim': dim if dim is not None and dim != [] else [0],
2630 2631
            'keep_dim': keep_dim,
            'reduce_all': True
2632
            if dim is None or dim == [] or len(dim) == len(input.shape)
2633 2634 2635
            else False,
        },
    )
2636 2637 2638
    return out


C
caoying03 已提交
2639
def split(input, num_or_sections, dim=-1, name=None):
G
guosheng 已提交
2640
    """
2641
    Split the input tensor into multiple sub-Tensors.
G
guosheng 已提交
2642 2643

    Args:
2644
        input (Tensor): A N-D Tensor. The data type is bool, float16, float32, float64, int32 or int64.
2645
        num_or_sections (int|list|tuple): If ``num_or_sections`` is int, then the ``num_or_sections``
2646
            indicates the number of equal sized sub-Tensors that the ``input``
2647
            will be divided into. If ``num_or_sections`` is a list or tuple, the length of it
2648 2649 2650 2651 2652
            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.
2653
        name (str, optional): The default value is None.  Normally there is no need for user to set this property.
2654
            For more information, please refer to :ref:`api_guide_Name` .
G
guosheng 已提交
2655 2656

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

2659
    Example:
G
guosheng 已提交
2660 2661
        .. code-block:: python

2662 2663
            import paddle.fluid as fluid

2664
            # input is a Tensor which shape is [3, 9, 5]
2665
            input = fluid.data(
2666 2667
                 name="input", shape=[3, 9, 5], dtype="float32")

2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681
            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]
2682

2683 2684 2685 2686 2687 2688
            # 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]
2689

G
guosheng 已提交
2690
    """
J
Jiabin Yang 已提交
2691
    if _non_static_mode():
2692 2693 2694
        num = None
        attrs = ()

S
songyouwei 已提交
2695 2696
        if isinstance(dim, Variable):
            dim = dim.numpy()
2697
            dim = dim.item(0)
W
wangzhen38 已提交
2698
        assert len(input.shape) + dim >= 0, "(rank(x) + axis) must >= 0"
S
songyouwei 已提交
2699
        dim = (len(input.shape) + dim) if dim < 0 else dim
2700
        attrs += ('axis', dim)
2701 2702 2703

        if isinstance(num_or_sections, int):
            num = num_or_sections
2704
            attrs += ('num', num_or_sections)
L
Leo Chen 已提交
2705
        elif isinstance(num_or_sections, (list, tuple)):
2706
            num = len(num_or_sections)
L
Leo Chen 已提交
2707
            if utils._contain_var(num_or_sections):
2708 2709
                for index, item in enumerate(num_or_sections):
                    if isinstance(item, Variable):
2710 2711 2712
                        num_or_sections[index] = num_or_sections[index].numpy()[
                            0
                        ]
2713
                attrs += ('sections', list(num_or_sections))
L
Leo Chen 已提交
2714
            else:
2715
                attrs += ('sections', list(num_or_sections))
2716 2717
        else:
            raise TypeError(
2718
                "The type of 'num_or_sections' in split must be int, list or tuple in imperative mode, but "
2719 2720
                "received %s." % (type(num_or_sections))
            )
2721
        if in_dygraph_mode():
C
Charles-hit 已提交
2722 2723 2724 2725
            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)
2726 2727
        elif _in_legacy_dygraph():
            out = [_varbase_creator() for n in range(num)]
2728
            _legacy_C_ops.split(input, out, *attrs)
2729
            return out
L
Leo Chen 已提交
2730

2731
    check_variable_and_dtype(
2732 2733 2734 2735 2736
        input,
        'input',
        ['bool', 'float16', 'float32', 'float64', 'int32', 'int64'],
        'split',
    )
2737 2738 2739 2740
    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')
2741

G
guosheng 已提交
2742
    helper = LayerHelper('split', **locals())
2743

G
guosheng 已提交
2744
    input_shape = input.shape
2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755
    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:
2756
                assert isinstance(dim_size, int)
2757 2758 2759
                if dim_size == -1:
                    assert unk_dim_idx == -1, (
                        "Only one value of 'num_or_section' in split can "
2760 2761 2762
                        "be -1. But received num_or_section[%d] is also -1."
                        % idx
                    )
2763 2764
                    unk_dim_idx = idx
                temp_out = helper.create_variable_for_type_inference('int32')
2765 2766 2767
                fill_constant(
                    [1], 'int32', dim_size, force_cpu=True, out=temp_out
                )
2768 2769 2770 2771 2772 2773 2774
                tensor_list.append(temp_out)
        return tensor_list

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

G
guosheng 已提交
2779 2780
    if isinstance(num_or_sections, int):
        assert num_or_sections > 1, 'num_or_sections must be more than 1.'
2781
        if isinstance(dim, int) and input_shape[dim] > 0:
2782 2783 2784 2785 2786 2787
            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 已提交
2788 2789
        num = num_or_sections
    else:
2790
        if isinstance(dim, int) and input_shape[dim] > 0:
2791 2792 2793
            assert (
                len(num_or_sections) <= input_shape[dim]
            ), 'len(num_or_sections) must not be more than input.shape[dim].'
G
guosheng 已提交
2794
        num = len(num_or_sections)
2795
        attrs['sections'] = list(
2796 2797 2798 2799 2800
            map(
                lambda ele: -1 if isinstance(ele, Variable) else ele,
                num_or_sections,
            )
        )
L
Leo Chen 已提交
2801
        if utils._contain_var(num_or_sections):
2802
            inputs['SectionsTensorList'] = _get_SectionsTensorList(
2803 2804
                num_or_sections
            )
2805

G
guosheng 已提交
2806
    outs = [
X
Xin Pan 已提交
2807
        helper.create_variable_for_type_inference(dtype=helper.input_dtype())
G
guosheng 已提交
2808 2809
        for i in range(num)
    ]
2810 2811 2812
    helper.append_op(
        type='split', inputs=inputs, outputs={'Out': outs}, attrs=attrs
    )
G
guosheng 已提交
2813
    return outs
C
caoying03 已提交
2814 2815 2816


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

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

2822
    .. math::
2823 2824

        y = \\frac{x}{ \sqrt{\sum {x^2} + epsion }}
C
caoying03 已提交
2825 2826 2827 2828 2829

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

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

C
caoying03 已提交
2838
    Returns:
R
ruri 已提交
2839
        Variable: The output has the same shape and data type with `x`.
C
caoying03 已提交
2840 2841

    Examples:
2842

2843 2844
    .. code-block:: python
        :name: code-example1
2845

2846
        import paddle
2847

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

2852 2853 2854
        # [[ 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]]
2855

C
caoying03 已提交
2856
    """
F
fengjiayi 已提交
2857 2858
    if len(x.shape) == 1:
        axis = 0
J
Jiabin Yang 已提交
2859
    if _non_static_mode():
2860 2861 2862
        if in_dygraph_mode():
            out, _ = _C_ops.norm(x, 1 if axis is None else axis, epsilon, False)
        elif _in_legacy_dygraph():
2863 2864 2865
            _, out = _legacy_C_ops.norm(
                x, 'axis', 1 if axis is None else axis, 'epsilon', epsilon
            )
2866 2867 2868
        return out

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

2870
    helper = LayerHelper("l2_normalize", **locals())
X
Xin Pan 已提交
2871 2872
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
    norm = helper.create_variable_for_type_inference(dtype=x.dtype)
2873 2874 2875 2876 2877 2878 2879 2880 2881
    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 已提交
2882
    return out
2883 2884


S
ShenLiang 已提交
2885
@deprecated(since="2.0.0", update_to="paddle.matmul")
S
sneaxiy 已提交
2886
def matmul(x, y, transpose_x=False, transpose_y=False, alpha=1.0, name=None):
G
guosheng 已提交
2887
    """
Y
ying 已提交
2888 2889 2890 2891
    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 已提交
2892

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

2896 2897 2898 2899 2900
    - 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
2901
      :math:`[1, D]` in transposed form.
G
guosheng 已提交
2902

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

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

Y
ying 已提交
2911 2912
    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 已提交
2913
    removed after matrix multiplication.
G
guosheng 已提交
2914 2915 2916

    Args:
        x (Variable): The input variable which is a Tensor or LoDTensor.
2917 2918 2919
        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 已提交
2920
        alpha (float): The scale of output. Default 1.0.
2921
        name(str|None): A name for this layer(optional). If set None, the layer
2922
            will be named automatically.
G
guosheng 已提交
2923 2924

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

G
guosheng 已提交
2927 2928 2929
    Examples:
        .. code-block:: python

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

2934
            # x: [B, M, K], y: [B, K, N]
2935
            # fluid.layers.matmul(x, y)  # out: [B, M, N]
Y
ying 已提交
2936

2937
            # x: [B, M, K], y: [K, N]
2938
            # fluid.layers.matmul(x, y)  # out: [B, M, N]
Y
ying 已提交
2939

2940
            # x: [M, K], y: [K, N]
2941
            # fluid.layers.matmul(x, y)  # out: [M, N]
Y
ying 已提交
2942 2943

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

2946
            # x: [K], y: [K]
2947
            # fluid.layers.matmul(x, y)  # out: [1]
2948

Y
ying 已提交
2949
            # x: [M], y: [N]
2950 2951
            # fluid.layers.matmul(x, y, True, True)  # out: [M, N]

2952
            import paddle
2953
            import paddle.fluid as fluid
2954 2955
            paddle.enable_static()

2956 2957 2958
            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 已提交
2959
    """
J
Jiabin Yang 已提交
2960
    if _non_static_mode():
S
ShenLiang 已提交
2961
        out = _varbase_creator(dtype=x.dtype)
2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972
        _legacy_C_ops.matmul(
            x,
            y,
            out,
            'transpose_X',
            transpose_x,
            'transpose_Y',
            transpose_y,
            'alpha',
            float(alpha),
        )
S
ShenLiang 已提交
2973 2974 2975 2976 2977
        return out

    def __check_input(x, y):
        var_names = {'x': x, 'y': y}
        for name, val in var_names.items():
2978 2979 2980
            check_variable_and_dtype(
                val, name, ['float16', 'float32', 'float64'], 'matmul'
            )
S
ShenLiang 已提交
2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993
        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]:
2994 2995 2996 2997 2998 2999
            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 已提交
3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010

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

W
wanghuancoder 已提交
3014 3015 3016 3017 3018 3019
    attrs = {
        'transpose_X': transpose_x,
        'transpose_Y': transpose_y,
        'alpha': float(alpha),
    }

S
ShenLiang 已提交
3020 3021 3022 3023
    __check_input(x, y)

    helper = LayerHelper('matmul', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
3024 3025 3026 3027 3028 3029
    helper.append_op(
        type='matmul',
        inputs={'X': x, 'Y': y},
        outputs={'Out': out},
        attrs=attrs,
    )
S
ShenLiang 已提交
3030
    return out
3031 3032


3033
def topk(input, k, name=None):
Q
qingqing01 已提交
3034
    """
3035
    :alias_main: paddle.topk
3036 3037
        :alias: paddle.topk,paddle.tensor.topk,paddle.tensor.search.topk
        :old_api: paddle.fluid.layers.topk
3038

3039
    This OP is used to find values and indices of the k largest entries
Q
qingqing01 已提交
3040 3041
    for the last dimension.

3042 3043
    If the input is a 1-D Tensor, finds the k largest entries and outputs
    their values and indices.
Q
qingqing01 已提交
3044 3045 3046 3047

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

F
fengjiayi 已提交
3048 3049
    .. code-block:: text

3050 3051 3052 3053 3054
        Case 1:

          Input:
            input.shape = [3, 4]
            input.data = [[5, 4, 2, 3],
F
fengjiayi 已提交
3055 3056 3057 3058
                     [9, 7, 10, 25],
                     [6, 2, 10, 1]]
            k = 2

3059
          Output:
F
fengjiayi 已提交
3060
            The first output:
3061 3062
            values.shape = [3, 2]
            values.data = [[5, 4],
F
fengjiayi 已提交
3063 3064 3065 3066
                      [10, 25],
                      [6, 10]]

            The second output:
3067 3068
            indices.shape = [3, 2]
            indices.data = [[0, 1],
F
fengjiayi 已提交
3069 3070 3071
                       [2, 3],
                       [0, 2]]

Q
qingqing01 已提交
3072
    Args:
3073 3074 3075 3076
        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 已提交
3077 3078

    Returns:
3079 3080
        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 已提交
3081

F
fengjiayi 已提交
3082
    Raises:
3083
        ValueError: If :math:`k < 1` or :math:`k > last dimension of input`.
Q
qingqing01 已提交
3084 3085 3086 3087

    Examples:
        .. code-block:: python

3088
            import paddle.fluid as fluid
3089
            import paddle.fluid.layers as layers
3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102
            # 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 已提交
3103
    """
J
Jiabin Yang 已提交
3104
    if _non_static_mode():
3105
        _k = k.numpy().item(0) if isinstance(k, Variable) else k
3106
        out, indices = _legacy_C_ops.top_k(input, 'k', _k)
3107 3108 3109
        out.stop_gradient = True
        indices.stop_gradient = True
        return out, indices
3110

3111 3112
    inputs = {"X": [input]}
    attrs = {}
S
songyouwei 已提交
3113 3114 3115 3116 3117
    if isinstance(k, Variable):
        inputs['K'] = [k]
    else:
        attrs = {'k': k}

3118 3119 3120 3121
    helper = LayerHelper("top_k", **locals())
    values = helper.create_variable_for_type_inference(dtype=input.dtype)
    indices = helper.create_variable_for_type_inference(dtype="int64")

3122 3123 3124 3125 3126 3127
    helper.append_op(
        type="top_k",
        inputs=inputs,
        outputs={"Out": [values], "Indices": [indices]},
        attrs=attrs,
    )
Q
qingqing01 已提交
3128 3129 3130 3131 3132
    values.stop_gradient = True
    indices.stop_gradient = True
    return values, indices


3133 3134 3135
def ctc_greedy_decoder(
    input, blank, input_length=None, padding_value=0, name=None
):
3136
    r"""
S
SunGaofeng 已提交
3137
    This op is used to decode sequences by greedy policy by the following steps:
Y
yi.wu 已提交
3138

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

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

3148 3149 3150 3151 3152
    A simple example as below:

    .. code-block:: text

        Given:
S
SunGaofeng 已提交
3153
        (1) for lod mode:
3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164

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

3165
        input.lod = [[4, 4]]
M
minqiyang 已提交
3166

W
whs 已提交
3167
        Computation:
3168

W
whs 已提交
3169 3170 3171 3172 3173 3174
        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:
3175 3176 3177 3178 3179

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

3180
        output.lod = [[2, 1]]
3181

S
SunGaofeng 已提交
3182
        (2) for padding mode:
3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198

         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]
3199
        step2: Change the argmax result to use padding mode, then argmax result is
3200 3201 3202 3203 3204 3205 3206 3207 3208
                [[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 已提交
3209
    Parameters:
3210

3211 3212
        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 已提交
3213
                         where Lp is the sum of all input sequences' length and
3214 3215
                         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 已提交
3216
                         (not including the blank label). The data type can be float32 or float64.
Y
ying 已提交
3217
        blank(int): the blank label index of Connectionist Temporal
S
SunGaofeng 已提交
3218
                    Classification (CTC) loss, which is in the half-opened
Y
ying 已提交
3219
                    interval [0, num_classes + 1).
S
SunGaofeng 已提交
3220 3221
        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.
3222
        padding_value(int): padding value.
3223 3224 3225
        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`
3226 3227

    Returns:
S
SunGaofeng 已提交
3228 3229 3230 3231 3232
        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 [[]].

3233
        For padding mode, returns a tuple of (output, output_length), which was described as below:
S
SunGaofeng 已提交
3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244

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

3245 3246 3247 3248

    Examples:
        .. code-block:: python

3249
            # for lod mode
S
SunGaofeng 已提交
3250
            import paddle.fluid as fluid
S
SunGaofeng 已提交
3251
            x = fluid.data(name='x', shape=[None, 8], dtype='float32', lod_level=1)
3252
            cost = fluid.layers.ctc_greedy_decoder(input=x, blank=0)
3253 3254

            # for padding mode
S
SunGaofeng 已提交
3255 3256
            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')
3257 3258 3259
            out, out_len = fluid.layers.ctc_greedy_decoder(input=x_pad, blank=0,
                            input_length=x_pad_len)

W
wanghaoshuang 已提交
3260
    """
3261 3262 3263
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'ctc_greedy_decoder'
    )
3264

3265
    helper = LayerHelper("ctc_greedy_decoder", **locals())
Q
qingqing01 已提交
3266
    _, topk_indices = topk(input, k=1)
3267 3268

    # ctc align op
X
Xin Pan 已提交
3269
    ctc_out = helper.create_variable_for_type_inference(dtype="int64")
3270 3271

    if input_length is None:
3272 3273 3274 3275 3276 3277
        helper.append_op(
            type="ctc_align",
            inputs={"Input": [topk_indices]},
            outputs={"Output": [ctc_out]},
            attrs={"merge_repeated": True, "blank": blank},
        )
3278 3279 3280
        return ctc_out
    else:
        ctc_out_len = helper.create_variable_for_type_inference(dtype="int64")
3281
        ctc_input = paddle.squeeze(topk_indices, [2])
3282

3283 3284 3285 3286 3287 3288 3289 3290 3291 3292
        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,
            },
        )
3293
        return ctc_out, ctc_out_len
3294 3295


3296 3297 3298 3299 3300 3301 3302 3303 3304
def im2sequence(
    input,
    filter_size=1,
    stride=1,
    padding=0,
    input_image_size=None,
    out_stride=1,
    name=None,
):
3305
    r"""
3306 3307
    :api_attr: Static Graph

3308
    Extracts image patches from the input tensor to form a tensor of shape
L
Liufang Sang 已提交
3309 3310 3311
    {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
3312 3313
    output_height * output_width for an image, in which output_height and
    output_width are calculated by below equation:
3314 3315 3316

    .. math::

L
Liufang Sang 已提交
3317 3318 3319 3320
        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
3321

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

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

L
Liufang Sang 已提交
3327 3328 3329
        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.
3330

L
Liufang Sang 已提交
3331 3332
        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.
3333

L
Liufang Sang 已提交
3334 3335 3336 3337 3338
        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
3339
            padding_up = padding_down = padding_left = padding_right = padding.
L
Liufang Sang 已提交
3340
            Default is 0.
3341

L
Liufang Sang 已提交
3342 3343 3344 3345
        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 已提交
3346
            If out_stride is List,  it must contain two integers,
L
Liufang Sang 已提交
3347 3348 3349 3350 3351
            :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` .
3352 3353 3354

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

    Return Type: Variable
3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384

    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 已提交
3385 3386 3387
            filter = [2, 2]
            stride = [1, 1]
            padding = [0, 0]
3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399

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

3400
            output.dims = {8, 8}
3401

3402
            output.lod = [[4, 4]]
3403

T
Tink_Y 已提交
3404
    Examples:
3405 3406 3407

        .. code-block:: python

B
Bai Yifan 已提交
3408
            import paddle.fluid as fluid
3409 3410
            import paddle
            paddle.enable_static()
L
Liufang Sang 已提交
3411
            data = fluid.data(name='data', shape=[None, 3, 32, 32],
B
Bai Yifan 已提交
3412
                                     dtype='float32')
3413
            output = fluid.layers.im2sequence(
B
Bai Yifan 已提交
3414 3415
                input=data, stride=[1, 1], filter_size=[2, 2])

3416 3417

    """
3418 3419 3420
    assert (
        not _non_static_mode()
    ), "sequence layer is not supported in dygraph mode yet."
W
wanghaoshuang 已提交
3421

3422 3423
    check_variable_and_dtype(input, 'input', ['float32'], 'im2sequence')

W
wanghaoshuang 已提交
3424 3425 3426 3427 3428 3429 3430 3431 3432
    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])
3433
    inputs = {"X": input}
3434
    attrs = {"kernels": filter_size, "strides": stride, "paddings": padding}
3435 3436 3437 3438 3439
    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
3440
    helper = LayerHelper('im2sequence', **locals())
X
Xin Pan 已提交
3441
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
3442 3443 3444
    helper.append_op(
        type='im2sequence', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
3445
    return out
3446 3447


Y
yuyang18 已提交
3448
@templatedoc()
3449
def row_conv(input, future_context_size, param_attr=None, act=None):
Y
yuyang18 已提交
3450
    """
3451 3452
    :api_attr: Static Graph

Y
yuyang18 已提交
3453
    ${comment}
3454 3455

    Args:
Y
yuyang18 已提交
3456
        input (${x_type}): ${x_comment}.
Y
yangyaming 已提交
3457 3458
        future_context_size (int): Future context size. Please note, the shape
            of convolution kernel is [future_context_size + 1, D].
3459 3460 3461 3462 3463
        param_attr (ParamAttr): Attributes of parameters, including
            name, initializer etc.
        act (str): Non-linear activation to be applied to output variable.

    Returns:
Y
yuyang18 已提交
3464
        ${out_comment}.
3465 3466

    Examples:
B
Bai Yifan 已提交
3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478

      .. 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)
3479 3480
    """
    helper = LayerHelper('row_conv', **locals())
3481
    check_variable_and_dtype(input, 'input', ['float32'], 'row_conv')
3482
    dtype = helper.input_dtype()
3483
    filter_shape = [future_context_size + 1, input.shape[-1]]
3484 3485 3486
    filter_param = helper.create_parameter(
        attr=helper.param_attr, shape=filter_shape, dtype=dtype
    )
X
Xin Pan 已提交
3487
    out = helper.create_variable_for_type_inference(dtype)
3488 3489 3490 3491 3492
    helper.append_op(
        type='row_conv',
        inputs={'X': [input], 'Filter': [filter_param]},
        outputs={'Out': [out]},
    )
Y
yangyaming 已提交
3493
    return helper.append_activation(out)
3494 3495


Y
yuyang18 已提交
3496
@templatedoc()
3497
def multiplex(inputs, index, name=None):
3498
    """
Y
yuyang18 已提交
3499

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

3502
    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 已提交
3503

3504
    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 已提交
3505

3506
    For Example:
L
lujun 已提交
3507

3508
            .. code-block:: text
L
lujun 已提交
3509

3510
                Given:
L
lujun 已提交
3511

3512 3513 3514 3515
                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 已提交
3516

3517
                index = [[3],[0],[1],[2]]
L
lujun 已提交
3518

3519 3520 3521 3522
                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 已提交
3523 3524


3525
    Args:
3526 3527 3528 3529 3530
        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`.
3531
    Returns:
3532
        Tensor: Output of multiplex OP, with data type being float32, float64, int32, int64.
X
xuezhong 已提交
3533 3534

    Examples:
3535

X
xuezhong 已提交
3536 3537
        .. code-block:: python

3538
            import paddle
3539 3540 3541
            import numpy as np
            img1 = np.array([[1, 2], [3, 4]]).astype(np.float32)
            img2 = np.array([[5, 6], [7, 8]]).astype(np.float32)
3542 3543 3544
            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)
3545
            print(res) # [array([[5., 6.], [3., 4.]], dtype=float32)]
X
xuezhong 已提交
3546

3547
    """
3548 3549

    if _in_legacy_dygraph():
3550
        return _legacy_C_ops.multiplex(index, inputs)
3551
    if in_dygraph_mode():
3552
        return _C_ops.multiplex(inputs, index)
3553 3554
    helper = LayerHelper('multiplex', **locals())

3555 3556 3557
    check_type(inputs, 'inputs', (list), 'multiplex')
    if len(inputs) < 2:
        raise ValueError(
3558 3559
            "inputs should be a list object with at least 2 elements."
        )
3560
    for id, x in enumerate(inputs):
3561 3562 3563 3564 3565 3566
        check_variable_and_dtype(
            x,
            'input[' + str(id) + ']',
            ['float32', 'float64', 'int32', 'int64'],
            'multiplex',
        )
3567
    check_variable_and_dtype(index, "index", ['int32', 'int64'], 'multiplex')
3568 3569

    out = helper.create_variable_for_type_inference(inputs[0].dtype)
3570 3571 3572 3573 3574
    helper.append_op(
        type='multiplex',
        inputs={'X': inputs, 'Ids': index},
        outputs={'Out': [out]},
    )
3575
    return out
X
xuezhong 已提交
3576 3577


3578 3579
def smooth_l1(x, y, inside_weight=None, outside_weight=None, sigma=None):
    """
3580

Y
Yibing Liu 已提交
3581 3582
    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 已提交
3583
    For each instance, it computes the smooth L1 loss element by element first
T
tianshuo78520a 已提交
3584
    and then sums all the losses. So the shape of output Variable is
3585
    [batch_size, 1].
3586

3587 3588
    Args:
        x (Variable): A tensor with rank at least 2. The input value of smooth
Q
qingqing01 已提交
3589
            L1 loss op with shape [batch_size, dim1, ..., dimN].
3590
            A LoDTensor or Tensor with type float32.
3591
        y (Variable): A tensor with rank at least 2. The target value of smooth
Y
Yibing Liu 已提交
3592
            L1 loss op with same shape as :attr:`x`.
3593
            A LoDTensor or Tensor with type float32.
3594
        inside_weight (Variable|None):  A tensor with rank at least 2. This
3595 3596
            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 已提交
3597
            by this tensor element by element.
3598
            A Tensor with type float32.
3599
        outside_weight (Variable|None): A tensor with rank at least 2. This
3600 3601
            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 已提交
3602
            element by element.
3603
            A Tensor with type float32.
3604
        sigma (float|None): Hyper parameter of smooth L1 loss layer. A float
3605 3606
           scalar with default value 1.0.

3607
    Returns:
3608
        Variable: The output smooth L1 loss with shape [batch_size, 1].  A Tensor with type float32.
3609 3610 3611 3612

    Examples:
        .. code-block:: python

3613
            import paddle.fluid as fluid
3614
            import numpy as np
3615 3616
            import paddle
            paddle.enable_static()
3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627
            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)
3628

3629 3630 3631 3632
            #[array([[0.08220536],
            #       [0.36652038],
            #      [0.20541131]], dtype=float32)]

3633
    """
3634 3635
    check_variable_and_dtype(x, 'X', ['float32', 'float64'], 'smooth_l1_loss')
    check_variable_and_dtype(y, 'Y', ['float32', 'float64'], 'smooth_l1_loss')
3636

3637
    helper = LayerHelper('smooth_l1_loss', **locals())
3638

X
Xin Pan 已提交
3639 3640
    diff = helper.create_variable_for_type_inference(dtype=x.dtype)
    loss = helper.create_variable_for_type_inference(dtype=x.dtype)
3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651
    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},
    )
3652
    return loss
3653 3654


3655
@deprecated(since='2.0.0', update_to='paddle.nn.functional.one_hot')
3656
def one_hot(input, depth, allow_out_of_range=False):
3657
    """
3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695

    **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.],
3696
                        [0., 1., 0., 0.],
3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708
                        [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
3709
            The second dimension in X is 5, which is greater than depth.
3710 3711
            Allow_out_of_range =False means that does not allow the word id to exceed depth,
            so it throws an exception.
3712 3713

    Args:
3714 3715 3716
        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.
3717
        depth(scalar): An integer defining the :attr:`depth` of the one hot dimension. If input
3718
            is word id, depth is generally the dictionary size.
3719
        allow_out_of_range(bool): A bool value indicating whether the input
3720 3721 3722 3723
            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.
3724 3725

    Returns:
3726
        Variable: The one-hot representations of input. A Tensor or LoDTensor with type float32.
3727 3728

    Examples:
C
caoying03 已提交
3729
        .. code-block:: python
3730

3731
            import paddle
3732
            import paddle.fluid as fluid
3733 3734
            paddle.enable_static()

3735 3736 3737
            # 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)
3738
    """
J
Jiabin Yang 已提交
3739
    if _non_static_mode():
S
songyouwei 已提交
3740 3741 3742
        if isinstance(depth, Variable):
            depth = depth.numpy()
            assert depth.shape == (
3743 3744
                1,
            ), "depth of type Variable should have shape [1]"
3745
            depth = depth.item(0)
3746 3747 3748
        out = _legacy_C_ops.one_hot(
            input, 'depth', depth, 'allow_out_of_range', allow_out_of_range
        )
3749 3750
        out.stop_gradient = True
        return out
3751

3752
    helper = LayerHelper("one_hot", **locals())
3753
    check_variable_and_dtype(input, 'input', ['int32', 'int64'], 'one_hot')
3754
    check_type(depth, 'depth', (int, Variable), 'one_hot')
X
Xin Pan 已提交
3755
    one_hot_out = helper.create_variable_for_type_inference(dtype='float32')
3756

3757 3758
    if not isinstance(depth, Variable):
        # user attribute
3759
        inputs = {'X': input}
Y
Yi Liu 已提交
3760
        attrs = {'depth': depth, 'allow_out_of_range': allow_out_of_range}
3761
    else:
3762 3763 3764
        depth.stop_gradient = True
        inputs = {'X': input, 'depth_tensor': depth}
        attrs = {'allow_out_of_range': allow_out_of_range}
3765 3766 3767
    helper.append_op(
        type="one_hot", inputs=inputs, attrs=attrs, outputs={'Out': one_hot_out}
    )
3768
    one_hot_out.stop_gradient = True
3769
    return one_hot_out
Y
Yu Yang 已提交
3770 3771


Y
Yu Yang 已提交
3772
def autoincreased_step_counter(counter_name=None, begin=1, step=1):
Y
Yu Yang 已提交
3773
    """
3774 3775
    :api_attr: Static Graph

3776 3777
    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 已提交
3778
    and the step size is 1.
Y
Yu Yang 已提交
3779 3780

    Args:
Y
Yibing Liu 已提交
3781 3782 3783
        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 已提交
3784

3785
    Returns:
Y
Yibing Liu 已提交
3786
        Variable: The auto-increased Variable with data type int64.
Y
yi.wu 已提交
3787 3788 3789 3790

    Examples:
        .. code-block:: python

3791
           import paddle.fluid as fluid
3792 3793
           import paddle
           paddle.enable_static()
Y
yi.wu 已提交
3794
           global_step = fluid.layers.autoincreased_step_counter(
Y
Yibing Liu 已提交
3795
               counter_name='@LR_DECAY_COUNTER@', begin=0, step=1)
Y
Yu Yang 已提交
3796 3797
    """
    helper = LayerHelper('global_step_counter')
Y
Yu Yang 已提交
3798 3799
    if counter_name is None:
        counter_name = '@STEP_COUNTER@'
Y
Yu Yang 已提交
3800
    counter, is_new_var = helper.create_or_get_global_variable(
H
hong 已提交
3801 3802 3803 3804
        name=counter_name,
        dtype='int64',
        shape=[1],
        persistable=True,
3805 3806
        belong_to_optimizer=True,
    )
Y
Yu Yang 已提交
3807
    if is_new_var:
3808 3809 3810
        helper.set_variable_initializer(
            counter, initializer=Constant(value=begin - 1, force_cpu=True)
        )
W
Wu Yi 已提交
3811
        helper.main_program.global_block()._prepend_op(
Y
Yu Yang 已提交
3812 3813
            type='increment',
            inputs={'X': [counter]},
Y
Yu Yang 已提交
3814
            outputs={'Out': [counter]},
3815 3816
            attrs={'step': float(step)},
        )
Y
Yu Yang 已提交
3817 3818 3819
        counter.stop_gradient = True

    return counter
Y
yangyaming 已提交
3820 3821


3822
def unsqueeze(input, axes, name=None):
Y
Yibing Liu 已提交
3823
    """
3824
    Insert single-dimensional entries to the shape of a Tensor. Takes one
M
minqiyang 已提交
3825 3826
    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 已提交
3827

M
minqiyang 已提交
3828
    For example:
H
haowang101779990 已提交
3829 3830 3831

    .. code-block:: text

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

Y
Yibing Liu 已提交
3835
    Args:
3836
        input (Variable): The input Tensor to be unsqueezed. Supported data type: float32, float64, bool, int8, int32, int64.
3837
        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 .
3838
        name (str|None): Name for this layer.
Y
Yibing Liu 已提交
3839 3840

    Returns:
3841
        Variable: Unsqueezed Tensor, with the same data type as input.
Y
Yibing Liu 已提交
3842 3843 3844 3845

    Examples:
        .. code-block:: python

3846 3847 3848
            import paddle.fluid as fluid
            x = fluid.layers.data(name='x', shape=[5, 10])
            y = fluid.layers.unsqueeze(input=x, axes=[1])
3849

Y
Yibing Liu 已提交
3850
    """
J
Jiabin Yang 已提交
3851
    if _non_static_mode():
L
Leo Chen 已提交
3852 3853 3854
        if isinstance(axes, int):
            axes = [axes]
        elif isinstance(axes, Variable):
3855
            axes = axes.numpy().tolist()
L
Leo Chen 已提交
3856 3857 3858 3859 3860
        elif isinstance(axes, (list, tuple)):
            axes = [
                item.numpy().item(0) if isinstance(item, Variable) else item
                for item in axes
            ]
3861
        if _in_legacy_dygraph():
3862
            out, _ = _legacy_C_ops.unsqueeze2(input, 'axes', axes)
3863
            return out
3864
        return _C_ops.unsqueeze(input, axes)
3865 3866

    check_type(axes, 'axis/axes', (int, list, tuple, Variable), 'unsqueeze')
3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883
    check_variable_and_dtype(
        input,
        'input',
        [
            'float16',
            'float32',
            'float64',
            'bool',
            'int8',
            'int16',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        'unsqueeze',
    )
3884 3885 3886 3887 3888 3889 3890 3891 3892 3893
    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 已提交
3894
        if utils._contain_var(axes):
3895
            inputs["AxesTensorList"] = utils._convert_to_tensor_list(axes)
3896 3897 3898
        else:
            attrs["axes"] = axes

X
Xin Pan 已提交
3899 3900
    out = helper.create_variable_for_type_inference(dtype=input.dtype)
    x_shape = helper.create_variable_for_type_inference(dtype=input.dtype)
3901 3902 3903 3904 3905 3906
    helper.append_op(
        type="unsqueeze2",
        inputs=inputs,
        attrs=attrs,
        outputs={"Out": out, "XShape": x_shape},
    )
Y
Yibing Liu 已提交
3907

3908 3909
    return out

3910

Y
yangyaming 已提交
3911
def lod_reset(x, y=None, target_lod=None):
Y
yangyaming 已提交
3912
    """
Y
Yibing Liu 已提交
3913
    Set LoD of :attr:`x` to a new one specified by :attr:`y` or
3914 3915 3916 3917
    :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
3918
    :attr:`y.data` or :attr:`target_lod`, only one level LoD is supported.
Y
yangyaming 已提交
3919 3920 3921 3922 3923 3924

    .. code-block:: text

        * Example 1:

            Given a 1-level LoDTensor x:
3925
                x.lod =  [[ 2,           3,                   1 ]]
Y
yangyaming 已提交
3926 3927 3928
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

3929
            target_lod: [4, 2]
Y
yangyaming 已提交
3930 3931

            then we get a 1-level LoDTensor:
3932
                out.lod =  [[4,                          2]]
Y
yangyaming 已提交
3933 3934 3935 3936 3937 3938
                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:
3939
                x.lod =  [[2,            3,                   1]]
Y
yangyaming 已提交
3940 3941 3942 3943
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

            y is a Tensor:
3944
                y.data = [[2, 4]]
Y
yangyaming 已提交
3945 3946 3947
                y.dims = [1, 3]

            then we get a 1-level LoDTensor:
3948
                out.lod =  [[2,            4]]
Y
yangyaming 已提交
3949 3950 3951 3952 3953 3954
                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:
3955
                x.lod =  [[2,            3,                   1]]
Y
yangyaming 已提交
3956 3957 3958 3959
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

            y is a 2-level LoDTensor:
3960
                y.lod =  [[2, 2], [2, 2, 1, 1]]
Y
yangyaming 已提交
3961 3962 3963 3964
                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:
3965
                out.lod =  [[2, 2], [2, 2, 1, 1]]
Y
yangyaming 已提交
3966 3967 3968 3969
                out.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                out.dims = [6, 1]

    Args:
3970
        x (Variable): Input variable which could be a Tensor or LoDTensor.
3971
                      The data type should be int32, int64, float32 or float64.
3972 3973
        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.
3974 3975
                                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 已提交
3976
                                      as target LoD when :attr:`y` not provided.
Y
yangyaming 已提交
3977 3978

    Returns:
Y
Yibing Liu 已提交
3979
        Variable: Output variable with LoD specified by this layer.
Y
yangyaming 已提交
3980 3981

    Raises:
Y
Yibing Liu 已提交
3982
        ValueError: If :attr:`y` and :attr:`target_lod` are both None.
Y
yangyaming 已提交
3983 3984 3985 3986

    Examples:
        .. code-block:: python

3987
            import paddle.fluid as fluid
3988 3989 3990
            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 已提交
3991
    """
3992 3993 3994
    check_variable_and_dtype(
        x, 'x', ['float32', 'float64', 'int32', 'int64'], 'lod_reset'
    )
Y
yangyaming 已提交
3995
    helper = LayerHelper("lod_reset", **locals())
X
Xin Pan 已提交
3996
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
Y
yangyaming 已提交
3997
    if y is not None:
3998
        check_type(y, 'y', (Variable), 'lod_reset')
3999 4000 4001 4002
        # TODO: check y.lod_level = 0 dtype
        helper.append_op(
            type="lod_reset", inputs={'X': x, 'Y': y}, outputs={'Out': out}
        )
Y
yangyaming 已提交
4003
    elif target_lod is not None:
4004 4005 4006 4007 4008 4009
        helper.append_op(
            type="lod_reset",
            inputs={'X': x},
            attrs={'target_lod': target_lod},
            outputs={'Out': out},
        )
Y
yangyaming 已提交
4010
    else:
4011 4012 4013 4014
        raise ValueError("y and target_lod should not be both none.")
    return out


4015
def pad(x, paddings, pad_value=0.0, name=None):
4016
    r"""
4017
    :alias_main: paddle.nn.functional.pad
4018 4019
        :alias: paddle.nn.functional.pad,paddle.nn.functional.common.pad
        :old_api: paddle.fluid.layers.pad
4020

S
SunGaofeng 已提交
4021 4022
    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 已提交
4023

S
SunGaofeng 已提交
4024 4025 4026 4027
    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 已提交
4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045

    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 已提交
4046
        x (Variable): Tensor, data type is float32.
G
guosheng 已提交
4047
        paddings (list): A list of integers. Its elements specify the padded
S
SunGaofeng 已提交
4048
                         width before and after each dimension in turn.
4049
                         The length of :attr:`paddings` must be equal to
G
guosheng 已提交
4050 4051
                         :math:`rank(x) \\times 2`.
        pad_value (float): The constant value used to pad.
4052 4053
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
4054
                             For more information, please refer to :ref:`api_guide_Name`
G
guosheng 已提交
4055 4056

    Returns:
S
SunGaofeng 已提交
4057 4058 4059 4060
        The padded tensor, with the same data type and rank as :attr:`x`

    Return Type:
        Variable
G
guosheng 已提交
4061 4062 4063

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

4065
            # x is a rank 2 tensor variable
S
SunGaofeng 已提交
4066
            import paddle.fluid as fluid
4067 4068
            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 已提交
4069
    """
4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083
    check_variable_and_dtype(
        x,
        'x',
        [
            'float16',
            'float32',
            'float64',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        "pad",
    )
4084

4085 4086 4087 4088
    check_type(pad_value, 'pad_value', (float, int, Variable), 'pad')
    if isinstance(pad_value, int):
        pad_value = float(pad_value)

4089 4090
    helper = LayerHelper('pad', **locals())
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
4091
    out = helper.create_variable_for_type_inference(dtype)
4092 4093 4094 4095 4096 4097
    helper.append_op(
        type='pad',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'paddings': paddings, 'pad_value': pad_value},
    )
G
guosheng 已提交
4098
    return out
4099 4100


4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111
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',
):
4112
    """
4113

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

4116 4117
    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)
4118 4119
    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 已提交
4120
    and the resizing only applies on the three dimensions(depth, height and width).
4121

4122
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in the
4123 4124
    future and only use :attr:`out_shape` instead.

4125
    Supporting resample methods:
4126
        'LINEAR' : Linear interpolation
Q
update  
qiaolongfei 已提交
4127

4128
        'BILINEAR' : Bilinear interpolation
T
Tink_Y 已提交
4129

K
Kaipeng Deng 已提交
4130 4131
        'TRILINEAR' : Trilinear interpolation

4132
        'NEAREST' : Nearest neighbor interpolation
4133

4134
        'BICUBIC' : Bicubic interpolation
4135 4136

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

4139
    Nearest neighbor interpolation is to perform nearest neighbor interpolation
4140
    in both the 3rd dimension(in height direction) and the 4th dimension(in width
4141
    direction) on input tensor.
4142 4143 4144 4145 4146

    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
4147 4148
    again in the other direction.

4149 4150 4151
    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 已提交
4152
    The linear interpolation is performed on three directions.
4153

4154 4155 4156 4157
    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 已提交
4158

4159
    Align_corners and align_mode are optional parameters,the calculation method
4160 4161 4162 4163
    of interpolation can be selected by them.

    Example:

T
Tink_Y 已提交
4164
    .. code-block:: text
4165

T
Tink_Y 已提交
4166
        For scale:
4167

T
Tink_Y 已提交
4168
            if align_corners = True && out_size > 1 :
4169

T
Tink_Y 已提交
4170
              scale_factor = (in_size-1.0)/(out_size-1.0)
4171

T
Tink_Y 已提交
4172
            else:
4173

T
Tink_Y 已提交
4174
              scale_factor = float(in_size/out_size)
4175 4176


T
Tink_Y 已提交
4177
        Nearest neighbor interpolation:
4178

T
Tink_Y 已提交
4179 4180
          if:
              align_corners = False
4181

T
Tink_Y 已提交
4182 4183
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4184

T
Tink_Y 已提交
4185 4186
              H_out = floor (H_{in} * scale_{factor})
              W_out = floor (W_{in} * scale_{factor})
4187

T
Tink_Y 已提交
4188 4189
          else:
              align_corners = True
4190

T
Tink_Y 已提交
4191 4192
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4193

T
Tink_Y 已提交
4194 4195
              H_out = round(H_{in} * scale_{factor})
              W_out = round(W_{in} * scale_{factor})
4196

4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213
        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 已提交
4214 4215 4216 4217
        Bilinear interpolation:

          if:
              align_corners = False , align_mode = 0
4218

T
Tink_Y 已提交
4219 4220
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4221

T
Tink_Y 已提交
4222 4223
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5
4224

T
Tink_Y 已提交
4225
          else:
4226

T
Tink_Y 已提交
4227 4228
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4229

T
Tink_Y 已提交
4230 4231
              H_out = H_{in} * scale_{factor}
              W_out = W_{in} * scale_{factor}
4232

K
Kaipeng Deng 已提交
4233 4234 4235 4236
        Trilinear interpolation:

          if:
              align_corners = False , align_mode = 0
4237

K
Kaipeng Deng 已提交
4238 4239
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:
4240

K
Kaipeng Deng 已提交
4241 4242 4243 4244 4245 4246
              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:
4247

K
Kaipeng Deng 已提交
4248 4249 4250 4251
              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}
4252

4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264
        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 已提交
4265 4266
              H_out = H_{in} * scale_{factor}
              W_out = W_{in} * scale_{factor}
4267

4268

4269 4270
    For details of linear interpolation, please refer to Wikipedia:
    https://en.wikipedia.org/wiki/Linear_interpolation.
4271

4272
    For details of nearest neighbor interpolation, please refer to Wikipedia:
4273
    https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation.
4274

4275
    For details of bilinear interpolation, please refer to Wikipedia:
4276
    https://en.wikipedia.org/wiki/Bilinear_interpolation.
4277

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

4281 4282
    For details of bicubic interpolation, please refer to Wikipedia:
    https://en.wikipedia.org/wiki/Bicubic_interpolation
4283

R
ruri 已提交
4284
    Parameters:
4285
        input (Variable): 3-D, 4-D or 5-D Tensor, its data type is float32, float64, or uint8,
4286
                          its data format is specified by :attr:`data_format`.
4287
        out_shape (list|tuple|Variable|None): Output shape of image resize
4288 4289
             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.
4290
             Default: None. If a list, each element can be an integer or a Tensor Variable of shape: [1].
4291
             If a Tensor Variable, its dimensions size should be a 1.
4292 4293 4294
        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 已提交
4295
             Default: None.
4296 4297
        name(str|None): A name for this layer(optional). If set None, the layer
                        will be named automatically.
4298
        resample(str): The resample method. It supports 'LINEAR', 'BICUBIC', 'BILINEAR', 'TRILINEAR'
K
Kaipeng Deng 已提交
4299
                       and 'NEAREST' currently. Default: 'BILINEAR'
4300 4301 4302
        actual_shape(Variable): An optional input to specify output shape
                                dynamically. If provided, image resize
                                according to this given shape rather than
4303
                                :attr:`out_shape` and :attr:`scale` specifying
4304 4305
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
4306 4307 4308 4309 4310
                                :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 已提交
4311
                                errors would be occurred in graph constructing stage.
4312
                                Default: None
4313 4314
        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
4315 4316
                               corner pixels.
                               Default: True
4317 4318
        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 ,
4319
                            can be \'1\' for src_idx = scale*dst_index.
4320
        data_format (str, optional): Specify the data format of the input, and the data format of the output
4321
            will be consistent with that of the input. An optional string from:`NCW`, `NWC`, `"NCHW"`, `"NHWC"`, `"NCDHW"`,
4322
            `"NDHWC"`. The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
4323
            `[batch_size, input_channels, input_height, input_width]`. When it is `"NCHW"`, the data is stored
4324
            in the order of: `[batch_size, input_channels, input_depth, input_height, input_width]`.
4325 4326

    Returns:
4327
        A 3-D Tensor of the shape (num_batches, channels, out_w) or (num_batches, out_w, channels),
4328 4329
        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 已提交
4330

4331 4332 4333
    Raises:
        TypeError: out_shape should be a list or tuple or Variable.
        TypeError: actual_shape should either be Variable or None.
4334 4335
        ValueError: The 'resample' of image_resize can only be 'LINEAR', 'BILINEAR',
                    'TRILINEAR', 'BICUBIC' or 'NEAREST' currently.
4336
        ValueError: 'LINEAR' only support 3-D tensor.
4337
        ValueError: 'BICUBIC', 'BILINEAR' and 'NEAREST' only support 4-D tensor.
K
Kaipeng Deng 已提交
4338
        ValueError: 'TRILINEAR' only support 5-D tensor.
4339
        ValueError: One of out_shape and scale must not be None.
4340
        ValueError: out_shape length should be 1 for input 3-D tensor.
K
Kaipeng Deng 已提交
4341 4342
        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 已提交
4343
        ValueError: scale should be greater than zero.
T
tianshuo78520a 已提交
4344
        TypeError: align_corners should be a bool value
4345
        ValueError: align_mode can only be '0' or '1'
4346
        ValueError: data_format can only be 'NCW', 'NWC', 'NCHW', 'NHWC', 'NCDHW' or 'NDHWC'.
4347

4348 4349
    Examples:
        .. code-block:: python
4350

4351 4352 4353 4354 4355 4356
            #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 已提交
4357

4358 4359
            #1
            output = fluid.layers.image_resize(input=input,out_shape=[12,12])
R
ruri 已提交
4360

4361 4362 4363 4364 4365
            #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 已提交
4366

4367 4368 4369 4370 4371
            #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 已提交
4372

4373 4374 4375 4376 4377
            #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 已提交
4378

4379 4380 4381
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
4382

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

4385
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
4386 4387 4388
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
4389

4390
            print(output_data[0].shape)
4391

4392 4393 4394 4395 4396 4397 4398 4399
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
4400

4401 4402
            #imperative mode
            import paddle.fluid.dygraph as dg
4403

4404 4405 4406 4407
            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)
4408

4409
                # [2L, 3L, 12L, 12L]
4410

4411
    """
4412
    resample_methods = {
4413
        'LINEAR': 'linear',
4414
        'BILINEAR': 'bilinear',
K
Kaipeng Deng 已提交
4415
        'TRILINEAR': 'trilinear',
4416
        'NEAREST': 'nearest',
4417
        'LINEAR': 'linear',
4418
    }
4419
    resample = resample.upper()
4420 4421
    if resample not in resample_methods:
        raise ValueError(
4422
            "The 'resample' of image_resize can only be 'LINEAR', 'BILINEAR', 'TRILINEAR' "
4423 4424
            "or 'NEAREST' currently."
        )
4425
    resample_type = resample_methods[resample]
4426

4427 4428 4429
    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 已提交
4430
        raise ValueError("'BILINEAR' and 'NEAREST' only support 4-D tensor.")
4431
    elif resample == 'TRILINEAR' and len(input.shape) != 5:
K
Kaipeng Deng 已提交
4432 4433
        raise ValueError("'TRILINEAR'only support 5-D tensor.")

4434 4435 4436 4437 4438
    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")

4439
    if out_shape is None and scale is None:
4440
        raise ValueError("One of out_shape and scale must not be None.")
4441
    helper = LayerHelper('{}_interp'.format(resample_type), **locals())
4442
    dtype = helper.input_dtype()
4443

4444
    if len(input.shape) == 3 and data_format not in ['NCW', 'NWC']:
4445
        raise ValueError(
4446 4447 4448 4449
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCW` or `NWC` supported for 3-D input."
        )
4450
    elif len(input.shape) == 4 and data_format not in ['NCHW', 'NHWC']:
4451
        raise ValueError(
4452 4453 4454 4455
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCHW` or `NHWC` supported for 4-D input."
        )
4456 4457
    elif len(input.shape) == 5 and data_format not in ['NCDHW', 'NDHWC']:
        raise ValueError(
4458 4459 4460 4461
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCDHW` or `NDHWC` supported for 5-D input."
        )
4462

4463
    def _is_list_or_turple_(data):
4464
        return isinstance(data, list) or isinstance(data, tuple)
4465

4466
    if data_format == 'NCHW' or data_format == 'NCDHW' or data_format == 'NCW':
4467
        data_layout = 'NCHW'
4468
    if data_format == 'NHWC' or data_format == 'NDHWC' or data_format == 'NWC':
4469 4470
        data_layout = 'NHWC'

4471
    inputs = {"X": input}
D
dengkaipeng 已提交
4472
    attrs = {
4473 4474 4475
        "out_d": -1,
        "out_h": -1,
        "out_w": -1,
D
dengkaipeng 已提交
4476 4477
        "interp_method": resample_type,
        "align_corners": align_corners,
4478
        "align_mode": align_mode,
4479
        "data_layout": data_layout,
D
dengkaipeng 已提交
4480 4481
    }

4482
    if out_shape is not None:
4483
        if isinstance(out_shape, Variable) and not _non_static_mode():
4484
            out_shape.stop_gradient = True
4485
            inputs['OutSize'] = out_shape
4486
        else:
4487 4488 4489 4490 4491 4492 4493 4494
            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]
4495
            if not (_is_list_or_turple_(out_shape)):
D
dengkaipeng 已提交
4496
                raise TypeError(
4497 4498
                    "out_shape should be a list or tuple or Variable."
                )
4499 4500 4501 4502 4503 4504
            # Validate the shape
            contain_var = False
            for dim_idx, dim_size in enumerate(out_shape):
                if isinstance(dim_size, Variable):
                    contain_var = True
                    continue
4505 4506 4507
                assert (
                    dim_size > 0
                ), "Each dimension size given in out_shape must be greater than 0."
4508 4509 4510 4511 4512 4513 4514 4515 4516 4517

            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:
4518
                        assert isinstance(dim, int)
4519
                        temp_out = helper.create_variable_for_type_inference(
4520 4521 4522 4523 4524
                            'int32'
                        )
                        fill_constant(
                            [1], 'int32', dim, force_cpu=True, out=temp_out
                        )
4525 4526 4527 4528
                        new_size_tensor.append(temp_out)
                        size_list.append(dim)
                inputs['SizeTensor'] = new_size_tensor

4529 4530
            if len(input.shape) == 3:
                if len(out_shape) != 1:
4531 4532 4533
                    raise ValueError(
                        "out_shape length should be 1 for " "input 3-D tensor."
                    )
4534 4535 4536 4537 4538 4539
                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 已提交
4540
                if len(out_shape) != 2:
4541 4542 4543
                    raise ValueError(
                        "out_shape length should be 2 for " "input 4-D tensor."
                    )
4544 4545 4546 4547 4548 4549 4550
                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 已提交
4551 4552
            if len(input.shape) == 5:
                if len(out_shape) != 3:
4553 4554 4555
                    raise ValueError(
                        "out_shape length should be 3 for " "input 5-D tensor."
                    )
4556 4557 4558 4559 4560 4561 4562 4563 4564
                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]
4565

4566
    else:
4567 4568 4569
        if _non_static_mode() and isinstance(scale, Variable):
            scale = scale.numpy()
        elif isinstance(scale, Variable):
4570 4571
            scale.stop_gradient = True
            inputs["Scale"] = scale
4572
        elif isinstance(scale, float) or isinstance(scale, int):
4573
            if scale <= 0:
4574
                raise ValueError("Attr(scale) should be greater than zero.")
4575
            attrs['scale'] = float(scale)
4576 4577
        else:
            raise TypeError(
4578 4579
                "Attr(scale)'s type should be float, int or Variable."
            )
4580

4581
    if isinstance(actual_shape, Variable):
4582 4583 4584 4585 4586
        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
4587 4588 4589
        inputs["OutSize"] = actual_shape
    elif actual_shape is not None:
        raise TypeError("actual_shape should either be Variable or None.")
4590 4591 4592 4593 4594 4595 4596 4597 4598

    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":
4599
            out = _legacy_C_ops.linear_interp(input, actual_shape, *dy_attr)
4600
        elif resample_type == "bilinear":
4601
            out = _legacy_C_ops.bilinear_interp(input, actual_shape, *dy_attr)
4602
        elif resample_type == "trilinear":
4603
            out = _legacy_C_ops.trilinear_interp(input, actual_shape, *dy_attr)
4604
        elif resample_type == "nearest":
4605
            out = _legacy_C_ops.nearest_interp(input, actual_shape, *dy_attr)
4606
        elif resample_type == "bicubic":
4607
            out = _legacy_C_ops.bicubic_interp(input, actual_shape, *dy_attr)
4608 4609
        return out

X
Xin Pan 已提交
4610
    out = helper.create_variable_for_type_inference(dtype)
4611 4612 4613 4614 4615 4616
    helper.append_op(
        type='{}_interp'.format(resample_type),
        inputs=inputs,
        outputs={"Out": out},
        attrs=attrs,
    )
4617
    return out
F
stash  
fengjiayi 已提交
4618 4619


4620
@templatedoc(op_type="bilinear_interp")
4621 4622 4623 4624 4625 4626 4627 4628 4629 4630
def resize_bilinear(
    input,
    out_shape=None,
    scale=None,
    name=None,
    actual_shape=None,
    align_corners=True,
    align_mode=1,
    data_format='NCHW',
):
4631
    """
4632

R
ruri 已提交
4633
    This op resizes the input by performing bilinear interpolation based on given
4634
    output shape which specified by actual_shape, out_shape and scale
4635 4636
    in priority order.

4637
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in
4638 4639
    the future and only use :attr:`out_shape` instead.

4640 4641 4642 4643
    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
4644 4645
    again in the other direction.

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

4649
    Align_corners and align_mode are optional parameters,the calculation
4650 4651 4652 4653
    method of interpolation can be selected by them.

    Example:

T
Tink_Y 已提交
4654
    .. code-block:: text
4655

T
Tink_Y 已提交
4656
        For scale:
4657

T
Tink_Y 已提交
4658
            if align_corners = True && out_size > 1 :
4659

T
Tink_Y 已提交
4660
              scale_factor = (in_size-1.0)/(out_size-1.0)
4661

T
Tink_Y 已提交
4662
            else:
4663

4664
              scale_factor = float(in_size/out_size)
4665

T
Tink_Y 已提交
4666 4667 4668 4669
        Bilinear interpolation:

          if:
              align_corners = False , align_mode = 0
4670

T
Tink_Y 已提交
4671 4672
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4673

T
Tink_Y 已提交
4674 4675
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5
4676

T
Tink_Y 已提交
4677
          else:
T
tink2123 已提交
4678

T
Tink_Y 已提交
4679 4680 4681 4682
              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}
4683

R
ruri 已提交
4684 4685
    Parameters:
        input(Variable): 4-D Tensor(NCHW), its data type is float32, float64, or uint8,
4686
                          its data format is specified by :attr:`data_format`.
D
dengkaipeng 已提交
4687
        out_shape(list|tuple|Variable|None): Output shape of resize bilinear
4688 4689
            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
4690
            Tensor Variable, its dimension size should be 1.
4691
        scale(float|Variable|None): The multiplier for the input height or width. At
4692 4693
             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 已提交
4694
             Default: None.
4695 4696 4697
        actual_shape(Variable): An optional input to specify output shape
                                dynamically. If provided, image resize
                                according to this given shape rather than
4698
                                :attr:`out_shape` and :attr:`scale` specifying
4699 4700
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
4701 4702 4703 4704 4705
                                :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 已提交
4706
                                errors would be occurred in graph constructing stage.
4707
                                Default: None
4708 4709
        align_corners(bool): ${align_corners_comment}
        align_mode(bool): ${align_mode_comment}
4710
        data_format (str, optional): Specify the data format of the input, and the data format of the output
4711 4712 4713
            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 已提交
4714
        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 已提交
4715 4716

    Returns:
4717
        Variable: 4-D tensor(NCHW or NHWC).
4718

4719 4720
    Examples:
        .. code-block:: python
4721

4722 4723 4724 4725 4726 4727
            #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 已提交
4728

4729 4730
            #1
            output = fluid.layers.resize_bilinear(input=input,out_shape=[12,12])
R
ruri 已提交
4731

4732 4733 4734 4735 4736
            #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 已提交
4737

4738 4739 4740 4741 4742
            #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 已提交
4743

4744 4745 4746 4747 4748
            #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 已提交
4749

4750 4751 4752
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
4753

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

4756
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
4757 4758 4759
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
4760

4761
            print(output_data[0].shape)
4762

4763 4764 4765 4766 4767 4768 4769 4770
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
4771

4772 4773
            #imperative mode
            import paddle.fluid.dygraph as dg
4774

4775 4776 4777 4778
            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)
4779

4780
                # [2L, 3L, 12L, 12L]
4781

4782 4783
    """

4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'BILINEAR',
        actual_shape,
        align_corners,
        align_mode,
        data_format,
    )
4795 4796


K
Kaipeng Deng 已提交
4797
@templatedoc(op_type="trilinear_interp")
4798 4799 4800 4801 4802 4803 4804 4805 4806 4807
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 已提交
4808
    """
4809

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

4814
    **Warning:** the parameter :attr:`actual_shape` will be deprecated
4815 4816
    in the future and only use :attr:`out_shape` instead.

4817 4818 4819
    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 已提交
4820 4821 4822 4823 4824
    The linear interpolation is performed on three directions.

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

4825
    Align_corners and align_mode are optional parameters,the calculation
K
Kaipeng Deng 已提交
4826 4827 4828 4829 4830 4831 4832
    method of interpolation can be selected by them.

    Example:

    .. code-block:: text

        For scale:
4833

K
Kaipeng Deng 已提交
4834 4835 4836
            if align_corners = True && out_size > 1 :

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

K
Kaipeng Deng 已提交
4838
            else:
4839 4840

              scale_factor = float(in_size/out_size)
K
Kaipeng Deng 已提交
4841 4842 4843 4844

        Bilinear interpolation:

          if:
4845

K
Kaipeng Deng 已提交
4846
              align_corners = False , align_mode = 0
4847

K
Kaipeng Deng 已提交
4848 4849
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:
4850

K
Kaipeng Deng 已提交
4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863
              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 已提交
4864
    Parameters:
4865 4866
        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 已提交
4867
        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.
4868
        scale(float|Variable|None): The multiplier for the input depth, height or width.
4869 4870
             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 已提交
4871
             Default: None.
R
ruri 已提交
4872
        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 已提交
4873 4874 4875 4876 4877 4878
        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
4879 4880 4881 4882 4883
                                :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 已提交
4884
                                errors would be occurred in graph constructing stage.
K
Kaipeng Deng 已提交
4885 4886 4887
                                Default: None
        align_corners(bool): ${align_corners_comment}
        align_mode(bool): ${align_mode_comment}
4888
        data_format (str, optional): Specify the data format of the input, and the data format of the output
4889 4890 4891
            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 已提交
4892 4893

    Returns:
4894
        Variable: A 5-D Tensor(NCDHW or NDHWC)
K
Kaipeng Deng 已提交
4895 4896 4897

    Examples:
        .. code-block:: python
4898

4899 4900 4901 4902 4903 4904
            #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 已提交
4905

4906 4907
            #1
            output = fluid.layers.resize_trilinear(input=input,out_shape=[12,12,12])
R
ruri 已提交
4908

4909 4910 4911 4912 4913
            #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 已提交
4914

4915 4916 4917 4918 4919
            #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 已提交
4920

4921 4922 4923 4924 4925
            #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 已提交
4926

4927 4928 4929
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
4930

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

4933
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
4934 4935 4936
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
4937

4938
            print(output_data[0].shape)
R
ruri 已提交
4939

4940 4941 4942 4943 4944 4945 4946 4947
            #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 已提交
4948

4949 4950
            #imperative mode
            import paddle.fluid.dygraph as dg
4951

4952 4953 4954 4955
            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)
4956

4957
                # [2L, 3L, 12L, 12L, 12L]
4958 4959 4960



K
Kaipeng Deng 已提交
4961 4962
    """

4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'TRILINEAR',
        actual_shape,
        align_corners,
        align_mode,
        data_format,
    )
K
Kaipeng Deng 已提交
4974 4975


4976
@templatedoc(op_type="nearest_interp")
4977 4978 4979 4980 4981 4982 4983 4984 4985
def resize_nearest(
    input,
    out_shape=None,
    scale=None,
    name=None,
    actual_shape=None,
    align_corners=True,
    data_format='NCHW',
):
4986
    """
4987

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

4992
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in the
4993 4994
    future and only use :attr:`out_shape` instead.

4995 4996
    Example:

T
Tink_Y 已提交
4997 4998 4999
    .. code-block:: text

        For scale:
5000

T
Tink_Y 已提交
5001 5002
            if align_corners = True && out_size > 1 :
              scale_factor = (in_size-1.0)/(out_size-1.0)
5003

T
Tink_Y 已提交
5004
            else:
5005

T
Tink_Y 已提交
5006
              scale_factor = float(in_size/out_size)
5007

T
Tink_Y 已提交
5008
        Nearest neighbor interpolation:
5009

T
Tink_Y 已提交
5010 5011
          if:
              align_corners = False
5012

T
Tink_Y 已提交
5013 5014
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5015

T
Tink_Y 已提交
5016 5017
              H_out = floor(H_{in} * scale_{factor})
              W_out = floor(W_{in} * scale_{factor})
5018

T
Tink_Y 已提交
5019 5020
          else:
              align_corners = True
5021

T
Tink_Y 已提交
5022 5023
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5024

T
Tink_Y 已提交
5025 5026
              H_out = round(H_{in} * scale_{factor})
              W_out = round(W_{in} * scale_{factor})
5027 5028


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

R
ruri 已提交
5032
    Parameters:
5033 5034
        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 已提交
5035
        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.
5036
        scale(float|Variable|None): The multiplier for the input height or width. At
5037 5038 5039
             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 已提交
5040
        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`
5041
        actual_shape(Variable): An optional input to specify output shape
5042 5043
                                dynamically. If provided, image resize
                                according to this given shape rather than
5044
                                :attr:`out_shape` and :attr:`scale` specifying
5045 5046
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
5047 5048 5049 5050 5051
                                :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 已提交
5052
                                errors would be occurred in graph constructing stage.
5053
                                Default: None
5054
        align_corners(bool): ${align_corners_comment}
5055
        data_format (str, optional): Specify the data format of the input, and the data format of the output
5056 5057 5058
            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 已提交
5059 5060

    Returns:
5061
        Variable: 4-D tensor(NCHW or NHWC).
5062 5063 5064

    Examples:
        .. code-block:: python
5065

5066 5067 5068 5069 5070
            #declarative mode
            import paddle.fluid as fluid
            import numpy as np
            import paddle
            paddle.enable_static()
5071

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

5074 5075
            #1
            output = fluid.layers.resize_nearest(input=input,out_shape=[12,12])
R
ruri 已提交
5076

5077 5078 5079 5080 5081
            #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 已提交
5082

5083 5084 5085 5086 5087
            #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 已提交
5088

5089 5090 5091 5092 5093
            #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 已提交
5094

5095 5096 5097
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5098

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

5101
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
5102 5103 5104
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
5105

5106
            print(output_data[0].shape)
R
ruri 已提交
5107

5108 5109 5110 5111 5112 5113 5114 5115
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
5116

5117 5118
            #imperative mode
            import paddle.fluid.dygraph as dg
5119

5120 5121 5122 5123
            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 已提交
5124

5125
                # [2L, 3L, 12L, 12L]
5126 5127 5128



5129 5130
    """

5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'NEAREST',
        actual_shape,
        align_corners,
        align_mode=1,
        data_format=data_format,
    )
5142 5143


5144
@deprecated(since="2.0.0", update_to="paddle.nn.functional.relu")
5145
def relu(x, name=None):
W
wanghaoshuang 已提交
5146
    """
Z
zhupengyang 已提交
5147
    ${comment}
W
wanghaoshuang 已提交
5148 5149

    Args:
Z
zhupengyang 已提交
5150 5151 5152 5153
        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 已提交
5154 5155

    Returns:
Z
zhupengyang 已提交
5156
        Variable: ${out_comment}
W
wanghaoshuang 已提交
5157 5158 5159 5160 5161

    Examples:

        .. code-block:: python

5162
            import paddle.fluid as fluid
Z
zhupengyang 已提交
5163 5164 5165 5166 5167 5168 5169
            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. ]
5170
                #  [1.  2.6]]"""
5171 5172

    if in_dygraph_mode():
W
wanghuancoder 已提交
5173
        return _C_ops.relu(x)
5174 5175
    if _in_legacy_dygraph():
        return _legacy_C_ops.relu(x)
5176

5177 5178
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'relu')

5179
    inputs = {'X': [x]}
W
wanghaoshuang 已提交
5180
    helper = LayerHelper('relu', **locals())
W
wanghaoshuang 已提交
5181
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
5182
    out = helper.create_variable_for_type_inference(dtype)
5183 5184 5185
    helper.append_op(
        type="relu", inputs={"X": helper.input('x')}, outputs={"Out": out}
    )
W
wanghaoshuang 已提交
5186
    return out
5187 5188


G
fix  
gongweibao 已提交
5189 5190 5191
from paddle.fluid.framework import convert_np_dtype_to_dtype_


5192
@deprecated(since="2.0.0", update_to="paddle.normal")
G
gongweibao 已提交
5193
@templatedoc()
5194 5195 5196
def gaussian_random(
    shape, mean=0.0, std=1.0, seed=0, dtype='float32', name=None
):
G
fix  
gongweibao 已提交
5197
    """
5198 5199
    This OP returns a Tensor filled with random values sampled from a Gaussian
    distribution, with ``shape`` and ``dtype``.
G
fix  
gongweibao 已提交
5200 5201

    Args:
5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216
        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 已提交
5217 5218

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

5222
    Examples:
5223
       .. code-block:: python
5224

5225
            import paddle
5226
            import paddle.fluid as fluid
5227
            paddle.enable_static()
5228 5229

            # example 1:
5230
            # attr shape is a list which doesn't contain Tensor.
5231
            result_1 = fluid.layers.gaussian_random(shape=[3, 4])
5232 5233 5234
            # [[-0.31261674,  1.8736548,  -0.6274357,   0.96988016],
            #  [-0.12294637,  0.9554768,   1.5690808,  -1.2894802 ],
            #  [-0.60082096, -0.61138713,  1.5345167,  -0.21834975]]
5235 5236

            # example 2:
5237 5238 5239
            # 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)
5240
            result_2 = fluid.layers.gaussian_random(shape=[dim_1, dim_2])
5241 5242
            # [[ 0.51398206, -0.3389769,   0.23597084],
            #  [ 1.0388143,  -1.2015356,  -1.0499583 ]]
5243 5244

            # example 3:
5245
            # attr shape is a Tensor, the data type must be int64 or int32.
5246 5247
            var_shape = fluid.data(name='var_shape', shape=[2], dtype="int64")
            result_3 = fluid.layers.gaussian_random(var_shape)
5248 5249 5250 5251
            # if var_shape's value is [2, 3]
            # result_3 is:
            # [[-0.12310527,  0.8187662,   1.923219  ]
            #  [ 0.70721835,  0.5210541,  -0.03214082]]
5252

5253
       .. code-block:: python
5254

5255 5256
           # declarative mode
           # required: skiptest
5257 5258
           import numpy as np
           from paddle import fluid
5259

5260
           x = fluid.layers.gaussian_random((2, 3), std=2., seed=10)
5261

5262 5263 5264 5265
           place = fluid.CPUPlace()
           exe = fluid.Executor(place)
           start = fluid.default_startup_program()
           main = fluid.default_main_program()
5266

5267 5268
           exe.run(start)
           x_np, = exe.run(main, feed={}, fetch_list=[x])
5269

5270 5271 5272 5273 5274 5275 5276 5277 5278 5279
           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
5280

5281 5282 5283
           place = fluid.CPUPlace()
           with dg.guard(place) as g:
               x = fluid.layers.gaussian_random((2, 4), mean=2., dtype="float32", seed=10)
5284
               x_np = x.numpy()
5285 5286 5287
           x_np
           # array([[2.3060477 , 2.676496  , 3.9911983 , 0.9990833 ],
           #        [2.8675377 , 2.2279181 , 0.79029655, 2.8447366 ]], dtype=float32)
G
fix  
gongweibao 已提交
5288
    """
5289 5290
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
5291

5292 5293 5294
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
        place = _current_expected_place()
5295
        return _C_ops.gaussian(
5296 5297
            shape, float(mean), float(std), seed, dtype, place
        )
5298 5299

    if _in_legacy_dygraph():
5300
        shape = utils.convert_shape_to_list(shape)
5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312
        return _legacy_C_ops.gaussian_random(
            'shape',
            shape,
            'mean',
            float(mean),
            'std',
            float(std),
            'seed',
            seed,
            'dtype',
            dtype,
        )
5313 5314 5315

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

    inputs = {}
5318 5319 5320 5321
    attrs = {
        'mean': mean,
        'std': std,
        'seed': seed,
5322
        'dtype': dtype,
5323
        'use_mkldnn': False,
5324
    }
5325 5326 5327
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='gaussian_random/randn'
    )
5328

5329 5330
    helper = LayerHelper('gaussian_random', **locals())
    out = helper.create_variable_for_type_inference(dtype)
5331 5332 5333
    helper.append_op(
        type='gaussian_random', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
G
fix  
gongweibao 已提交
5334 5335 5336 5337

    return out


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

R
ruri 已提交
5343 5344 5345 5346
    Parameters:
        x (Variable): 2-D tensor, [batch_size, input_feature_dimensions]
        min (Float): minimum , default 0.0.
        max (Float): maximum, default 1.0.
5347
        seed (Float): Random seed, default 0. if seed is not 0, will generate same number every time.
G
fix  
gongweibao 已提交
5348
        dtype(np.dtype|core.VarDesc.VarType|str): The type of output data : float32, float_16, int etc
G
fix  
gongweibao 已提交
5349 5350

    Returns:
R
ruri 已提交
5351
        Variable: sampling tensor.
G
fix  
gongweibao 已提交
5352

5353 5354 5355
    Examples:
        .. code-block:: python

5356
            import paddle.fluid as fluid
R
ruri 已提交
5357
            x = fluid.data(
5358 5359
                name="X",
                shape=[13, 11],
R
ruri 已提交
5360
                dtype='float32')
5361

Y
Yibing Liu 已提交
5362
            out = fluid.layers.sampling_id(x)
G
fix  
gongweibao 已提交
5363 5364 5365
    """

    helper = LayerHelper('sampling_id', **locals())
X
Xin Pan 已提交
5366
    out = helper.create_variable_for_type_inference(dtype)
5367 5368 5369 5370 5371 5372
    helper.append_op(
        type='sampling_id',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'min': min, 'max': max, 'seed': seed},
    )
G
fix  
gongweibao 已提交
5373 5374 5375 5376 5377 5378

    return out


def shape(input):
    """
5379
    :alias_main: paddle.shape
5380 5381
        :alias: paddle.shape,paddle.tensor.shape,paddle.tensor.attribute.shape
        :old_api: paddle.fluid.layers.shape
5382

C
chengduozh 已提交
5383 5384
    **Shape Layer**

C
fix doc  
chengduozh 已提交
5385
    Get the shape of the input.
G
fix  
gongweibao 已提交
5386

5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403
    .. 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 已提交
5404
    Args:
5405
        input (Variable): The input can be N-D Tensor or SelectedRows with data type bool, float16, float32, float64, int32, int64.
5406
                          If input variable is type of SelectedRows, returns the shape of it's inner tensor.
G
fix  
gongweibao 已提交
5407 5408

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

5411 5412 5413
    Examples:
        .. code-block:: python

5414
            import paddle.fluid as fluid
5415
            import numpy as np
W
Wilber 已提交
5416 5417
            import paddle
            paddle.enable_static()
5418

5419
            inputs = fluid.data(name="x", shape=[3, 100, 100], dtype="float32")
5420 5421 5422 5423 5424 5425 5426 5427 5428
            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 已提交
5429
    """
5430
    if in_dygraph_mode():
5431
        out = _C_ops.shape(input)
5432 5433 5434
        out.stop_gradient = True
        return out
    if _in_legacy_dygraph():
5435
        out = _legacy_C_ops.shape(input)
W
Wilber 已提交
5436 5437 5438
        out.stop_gradient = True
        return out

5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453
    check_variable_and_dtype(
        input,
        'input',
        [
            'bool',
            'float16',
            'float32',
            'float64',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        'shape',
    )
G
fix  
gongweibao 已提交
5454
    helper = LayerHelper('shape', **locals())
5455
    out = helper.create_variable_for_type_inference(dtype='int32')
5456 5457 5458 5459 5460 5461
    helper.append_op(
        type='shape',
        inputs={'Input': input},
        outputs={'Out': out},
        stop_gradient=True,
    )
G
fix  
gongweibao 已提交
5462 5463

    return out
G
merge  
gongweibao 已提交
5464 5465


S
sneaxiy 已提交
5466 5467 5468 5469
def _elementwise_op(helper):
    op_type = helper.layer_type
    x = helper.kwargs.get('x', None)
    y = helper.kwargs.get('y', None)
X
Xin Pan 已提交
5470

S
sneaxiy 已提交
5471 5472
    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)
5473
    check_variable_and_dtype(
5474 5475 5476 5477 5478
        x,
        'x',
        ['float16', 'uint16', 'float32', 'float64', 'int32', 'int64'],
        op_type,
    )
5479
    check_variable_and_dtype(
5480 5481 5482 5483 5484
        y,
        'y',
        ['float16', 'uint16', 'float32', 'float64', 'int32', 'int64'],
        op_type,
    )
5485

S
sneaxiy 已提交
5486 5487
    axis = helper.kwargs.get('axis', -1)
    use_mkldnn = helper.kwargs.get('use_mkldnn', False)
S
sneaxiy 已提交
5488
    name = helper.kwargs.get('name', None)
5489
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
S
sneaxiy 已提交
5490

5491 5492 5493 5494 5495 5496
    helper.append_op(
        type=op_type,
        inputs={'X': x, 'Y': y},
        outputs={'Out': out},
        attrs={'axis': axis, 'use_mkldnn': use_mkldnn},
    )
S
sneaxiy 已提交
5497 5498 5499
    return helper.append_activation(out)


X
Xin Pan 已提交
5500
def elementwise_add(x, y, axis=-1, act=None, name=None):
5501
    """
5502

5503
    Examples:
5504

5505
        .. code-block:: python
5506

5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519
            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
5520

5521 5522 5523 5524
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5525

5526
            print(z_value) # [3., 8., 6.]
5527 5528


5529
        .. code-block:: python
5530

5531 5532 5533
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5534

5535 5536 5537 5538 5539 5540 5541 5542 5543 5544
            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
5545

5546 5547
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5548

5549 5550
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5551

5552
            print(z_value) # z.shape=[2,3,4,5]
5553 5554


5555
        ..  code-block:: python
5556

5557 5558 5559
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5560

5561 5562 5563 5564 5565 5566 5567 5568 5569 5570
            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
5571

5572 5573
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5574

5575 5576 5577
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
5578 5579

    """
J
Jiabin Yang 已提交
5580
    if _non_static_mode():
5581
        return _elementwise_op_in_dygraph(
5582 5583 5584 5585 5586
            x,
            y,
            axis=axis,
            act=act,
            op_name='elementwise_add',
5587 5588
            use_mkldnn=_global_flags()["FLAGS_use_mkldnn"],
        )
5589

S
sneaxiy 已提交
5590 5591 5592
    return _elementwise_op(LayerHelper('elementwise_add', **locals()))


5593
@deprecated(since="2.0.0", update_to="paddle.divide")
X
Xin Pan 已提交
5594
def elementwise_div(x, y, axis=-1, act=None, name=None):
5595
    """
5596

5597
    Examples:
5598

5599
        .. code-block:: python
5600

5601 5602 5603
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5604

5605 5606 5607 5608 5609 5610 5611 5612 5613 5614
            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
5615

5616 5617 5618 5619
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5620

5621
            print(z_value) # [2., 0.6, 2.]
5622 5623


5624
        .. code-block:: python
5625

5626 5627 5628
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5629

5630 5631 5632 5633 5634 5635 5636 5637 5638 5639
            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
5640

5641 5642
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5643

5644 5645
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5646

5647
            print(z_value) # z.shape=[2,3,4,5]
5648 5649


5650
        ..  code-block:: python
5651

5652 5653 5654
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5655

5656 5657 5658 5659 5660 5661 5662 5663 5664 5665
            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
5666

5667 5668
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5669

5670 5671 5672
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
5673 5674

    """
J
Jiabin Yang 已提交
5675
    if _non_static_mode():
5676 5677 5678
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_div'
        )
5679

S
sneaxiy 已提交
5680 5681 5682
    return _elementwise_op(LayerHelper('elementwise_div', **locals()))


X
Xin Pan 已提交
5683
def elementwise_sub(x, y, axis=-1, act=None, name=None):
5684
    """
5685

5686
    Examples:
5687

5688
        .. code-block:: python
5689

5690 5691 5692
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5693

5694 5695 5696 5697 5698 5699 5700 5701 5702 5703
            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
5704

5705 5706 5707 5708
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5709

5710
            print(z_value) # [1., -2., 2.]
5711 5712


5713
        .. code-block:: python
5714

5715 5716 5717
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5718

5719 5720 5721 5722 5723 5724 5725 5726 5727 5728
            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
5729

5730 5731
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5732

5733 5734
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5735

5736
            print(z_value) # z.shape=[2,3,4,5]
5737 5738


5739
        ..  code-block:: python
5740

5741 5742 5743
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5744

5745 5746 5747 5748 5749 5750 5751 5752 5753 5754
            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
5755

5756 5757
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5758

5759 5760 5761
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
5762 5763

    """
J
Jiabin Yang 已提交
5764
    if _non_static_mode():
5765 5766 5767
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_sub'
        )
5768

S
sneaxiy 已提交
5769 5770 5771
    return _elementwise_op(LayerHelper('elementwise_sub', **locals()))


5772
@deprecated(since="2.0.0", update_to="paddle.multiply")
X
Xin Pan 已提交
5773
def elementwise_mul(x, y, axis=-1, act=None, name=None):
5774
    """
5775

5776
    Examples:
5777

5778
        .. code-block:: python
5779

5780 5781 5782
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5783

5784 5785 5786 5787 5788 5789 5790 5791 5792 5793
            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
5794

5795 5796 5797 5798
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5799

5800
            print(z_value) # [2., 15., 8.]
5801 5802


5803
        .. code-block:: python
5804

5805 5806 5807
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5808

5809 5810 5811 5812 5813 5814 5815 5816 5817 5818
            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
5819

5820 5821
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5822

5823 5824
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
5825

5826
            print(z_value) # z.shape=[2,3,4,5]
5827 5828


5829
        ..  code-block:: python
5830

5831 5832 5833
            import paddle.fluid as fluid
            import numpy as np
            import paddle
5834

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

5846 5847
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
5848

5849 5850 5851
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
5852

5853
    """
J
Jiabin Yang 已提交
5854
    if _non_static_mode():
5855 5856 5857
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_mul'
        )
5858

S
sneaxiy 已提交
5859 5860 5861 5862
    return _elementwise_op(LayerHelper('elementwise_mul', **locals()))


for func in [
5863 5864 5865 5866
    elementwise_add,
    elementwise_div,
    elementwise_sub,
    elementwise_mul,
5867 5868
]:
    op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
5869 5870

    # insert the c++ doc string on top of python doc string
5871 5872 5873 5874 5875
    func.__doc__ = (
        _generate_doc_string_(
            op_proto,
            additional_args_lines=[
                "axis (int32, optional): If X.dimension != Y.dimension, \
5876 5877
            Y.dimension must be a subsequence of x.dimension. \
            And axis is the start dimension index for broadcasting Y onto X. ",
5878
                "act (string, optional): Activation applied to the output. \
5879
            Default is None. Details: :ref:`api_guide_activations_en` ",
5880
                "name (string, optional): Name of the output. \
5881
            Default is None. It's used to print debug info for developers. Details: \
5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897
            :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__)
    )
5898

5899 5900 5901
    doc_list = func.__doc__.splitlines()

    for idx, val in enumerate(doc_list):
5902 5903 5904 5905 5906
        if (
            val.startswith("Warning: ")
            and val.endswith(" instead.")
            and "and will be removed in future versions." in val
        ):
5907 5908 5909 5910
            doc_list.insert(0, doc_list.pop(idx))
            func.__doc__ = "\n" + "\n".join(i for i in doc_list)
            break

5911
for func in []:
S
sneaxiy 已提交
5912 5913 5914 5915
    op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
    func.__doc__ = _generate_doc_string_(
        op_proto,
        additional_args_lines=[
S
sneaxiy 已提交
5916
            "act (basestring|None): Activation applied to the output.",
5917 5918 5919 5920 5921 5922
            "name (basestring|None): Name of the output.",
        ],
    )
    func.__doc__ = (
        func.__doc__
        + """
5923 5924 5925

Examples:
  .. code-block:: python
5926

5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956
    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)
5957 5958 5959 5960 5961 5962 5963 5964 5965 5966
    """
        % (
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
        )
    )
M
minqiyang 已提交
5967 5968


5969
def _logical_op(op_name, x, y, out=None, name=None, binary_op=True):
J
Jiabin Yang 已提交
5970
    if _non_static_mode():
5971
        op = getattr(_legacy_C_ops, op_name)
5972 5973 5974 5975
        if binary_op:
            return op(x, y)
        else:
            return op(x)
5976
    check_variable_and_dtype(
5977 5978
        x,
        "x",
5979
        ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
5980 5981
        op_name,
    )
5982
    if y is not None:
5983
        check_variable_and_dtype(
5984 5985
            y,
            "y",
5986
            ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
5987 5988
            op_name,
        )
5989
    if out is not None:
5990
        check_type(out, "out", Variable, op_name)
5991

M
minqiyang 已提交
5992 5993
    helper = LayerHelper(op_name, **locals())

5994 5995 5996
    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."
5997 5998
            % (op_name, x.dtype, y.dtype)
        )
M
minqiyang 已提交
5999 6000

    if out is None:
6001
        out = helper.create_variable_for_type_inference(dtype=x.dtype)
M
minqiyang 已提交
6002 6003

    if binary_op:
6004 6005 6006
        helper.append_op(
            type=op_name, inputs={"X": x, "Y": y}, outputs={"Out": out}
        )
M
minqiyang 已提交
6007 6008 6009 6010 6011 6012
    else:
        helper.append_op(type=op_name, inputs={"X": x}, outputs={"Out": out})

    return out


6013 6014 6015
@templatedoc()
def clip(x, min, max, name=None):
    """
6016
        :old_api: paddle.fluid.layers.clip
6017

6018 6019 6020 6021
    ${comment}

    Args:
        x(${x_type}): ${x_comment}
S
SunGaofeng 已提交
6022 6023
        min(float): ${min_comment}
        max(float): ${max_comment}
6024 6025
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
6026
                             For more information, please refer to :ref:`api_guide_Name`
6027 6028

    Returns:
S
SunGaofeng 已提交
6029 6030 6031 6032
        ${out_comment}

    Return Type:
        ${out_type}
6033 6034 6035 6036

    Examples:
        .. code-block:: python

S
SunGaofeng 已提交
6037
            import paddle.fluid as fluid
S
SunGaofeng 已提交
6038
            input = fluid.data(
6039 6040
                name='data', shape=[1], dtype='float32')
            reward = fluid.layers.clip(x=input, min=-1.0, max=1.0)
6041 6042 6043
    """

    helper = LayerHelper("clip", **locals())
6044
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'clip')
6045 6046

    if name is None:
6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060
        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},
    )
6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072

    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}
6073 6074 6075
        name(str, optional): For detailed information, please refer
            to :ref:`api_guide_Name`. Usually name is no need to set and
            None by default.
6076 6077

    Returns:
6078
        Tensor:
W
wangguanzhong 已提交
6079

6080
        out(${out_type}): ${out_comment}
6081

W
wangguanzhong 已提交
6082

6083 6084 6085
    Examples:
        .. code-block:: python

6086
            import paddle
6087
            import paddle.fluid as fluid
6088

6089 6090 6091
            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]]
6092 6093
    """

L
lyq 已提交
6094
    if in_dygraph_mode():
6095
        return _C_ops.clip_by_norm(x, max_norm)
J
Jiabin Yang 已提交
6096
    if _non_static_mode():
6097
        return _legacy_C_ops.clip_by_norm(x, 'max_norm', max_norm)
6098

6099
    helper = LayerHelper("clip_by_norm", **locals())
6100
    check_variable_and_dtype(x, 'X', ['float32', 'float16'], 'clip_by_norm')
6101
    check_type(max_norm, 'max_norm', (float), 'clip_by_norm')
6102 6103

    if name is None:
6104 6105 6106
        name = unique_name.generate_with_ignorable_key(
            ".".join([helper.name, 'tmp'])
        )
S
sneaxiy 已提交
6107

6108 6109 6110
    out = helper.create_variable(
        type=x.type, name=name, dtype=x.dtype, persistable=False
    )
6111

6112 6113 6114 6115 6116 6117
    helper.append_op(
        type="clip_by_norm",
        inputs={"X": x},
        attrs={"max_norm": max_norm},
        outputs={"Out": out},
    )
6118 6119

    return out
X
Xin Pan 已提交
6120 6121


6122
@deprecated(since="2.0.0", update_to="paddle.mean")
X
Xin Pan 已提交
6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133
@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}
6134 6135 6136 6137

    Examples:
        .. code-block:: python

6138
            import paddle
6139
            import paddle.fluid as fluid
6140 6141
            paddle.enable_static()

6142 6143
            input = fluid.layers.data(
                name='data', shape=[2, 3], dtype='float32')
6144
            mean = paddle.mean(input)
X
Xin Pan 已提交
6145
    """
6146

6147
    if _in_legacy_dygraph():
6148
        return _legacy_C_ops.mean(x)
6149
    if in_dygraph_mode():
6150
        return _C_ops.mean_all(x)
X
Xin Pan 已提交
6151 6152

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

6156 6157 6158
    helper.append_op(
        type="mean", inputs={"X": x}, attrs={}, outputs={"Out": out}
    )
X
Xin Pan 已提交
6159 6160 6161 6162

    return out


C
chengduo 已提交
6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173
@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}
6174 6175 6176 6177

    Examples:
        .. code-block:: python

6178
            import paddle.fluid as fluid
6179 6180 6181 6182 6183
            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 已提交
6184
    """
6185 6186 6187
    if in_dygraph_mode():
        return _C_ops.merge_selected_rows(x)

6188
    if _non_static_mode():
6189
        return _legacy_C_ops.merge_selected_rows(x)
C
chengduo 已提交
6190 6191 6192

    helper = LayerHelper("merge_selected_rows", **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
6193 6194 6195 6196 6197 6198
    helper.append_op(
        type="merge_selected_rows",
        inputs={"X": x},
        attrs={},
        outputs={"Out": out},
    )
C
chengduo 已提交
6199 6200 6201
    return out


X
Xin Pan 已提交
6202 6203
def mul(x, y, x_num_col_dims=1, y_num_col_dims=1, name=None):
    """
L
liu zhengxi 已提交
6204 6205 6206 6207 6208 6209 6210 6211
    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 已提交
6212 6213

    Args:
L
liu zhengxi 已提交
6214 6215
        x (Variable): The first input Tensor/LoDTensor of mul_op.
        y (Variable): The second input Tensor/LoDTensor of mul_op.
6216 6217 6218
        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 已提交
6219 6220

    Returns:
L
liu zhengxi 已提交
6221
        Variable(Tensor/LoDTensor): The output Tensor/LoDTensor of mul op.
6222 6223

    Examples:
L
liu zhengxi 已提交
6224
        ..  code-block:: python
6225

6226
            import paddle.fluid as fluid
6227 6228
            import paddle
            paddle.enable_static()
6229 6230 6231 6232 6233
            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)
6234

6235

X
Xin Pan 已提交
6236
    """
J
Jiabin Yang 已提交
6237
    if _non_static_mode():
6238 6239 6240 6241 6242 6243 6244 6245
        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 已提交
6246

6247 6248
    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 已提交
6249
    helper = LayerHelper("mul", **locals())
6250 6251
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'mul')
    check_variable_and_dtype(y, 'y', ['float16', 'float32', 'float64'], 'mul')
6252
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
X
Xin Pan 已提交
6253

6254 6255 6256
    helper.append_op(
        type="mul", inputs={"X": x, "Y": y}, attrs=attrs, outputs={"Out": out}
    )
X
Xin Pan 已提交
6257 6258 6259
    return out


M
minqiyang 已提交
6260 6261
def hash(input, hash_size, num_hash=1, name=None):
    """
6262

Z
zhupengyang 已提交
6263
    This OP hash the input to an integer less than the hash_size.
M
minqiyang 已提交
6264 6265
    The hash algorithm we used was xxHash - Extremely fast hash algorithm
    (https://github.com/Cyan4973/xxHash/tree/v0.6.5)
M
minqiyang 已提交
6266 6267

    Args:
Z
zhupengyang 已提交
6268 6269 6270 6271 6272 6273
        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 已提交
6274 6275

    Returns:
Z
zhupengyang 已提交
6276
       Variable: A LoDTensor with the same data type as input.
M
minqiyang 已提交
6277 6278

    Examples:
Z
zhupengyang 已提交
6279
        .. code-block:: python
H
haowang101779990 已提交
6280

6281
            import paddle.fluid as fluid
Z
zhupengyang 已提交
6282
            import numpy as np
6283 6284
            import paddle
            paddle.enable_static()
6285

Z
zhupengyang 已提交
6286
            place = fluid.core.CPUPlace()
6287

6288 6289
            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)
6290

Z
zhupengyang 已提交
6291 6292 6293 6294
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
            in1 = np.array([[1,2],[3,4]]).astype("int32")
            print(in1)
6295
            x_i = fluid.create_lod_tensor(in1, [[0, 2]], place)
Z
zhupengyang 已提交
6296 6297 6298 6299 6300 6301 6302 6303 6304 6305
            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 已提交
6306
    """
6307
    check_variable_and_dtype(input, 'input', ['int32', 'int64'], 'hash')
6308 6309
    check_type(hash_size, 'hash_size', int, 'hash')
    check_type(num_hash, 'num_hash', int, 'hash')
M
minqiyang 已提交
6310
    helper = LayerHelper('hash', **locals())
6311 6312 6313 6314 6315 6316 6317 6318 6319
    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 已提交
6320
    return out
G
gmcather 已提交
6321 6322


D
dengkaipeng 已提交
6323
@templatedoc()
6324 6325
def grid_sampler(x, grid, name=None):
    """
6326

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

H
haowang101779990 已提交
6336
    .. code-block:: text
6337

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

K
Kaipeng Deng 已提交
6341 6342 6343 6344
        .. code-block:: text

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

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

H
haowang101779990 已提交
6350 6351 6352 6353 6354 6355 6356 6357 6358
          wn ------- y_n ------- en
          |           |           |
          |          d_n          |
          |           |           |
         x_w --d_w-- grid--d_e-- x_e
          |           |           |
          |          d_s          |
          |           |           |
          ws ------- y_s ------- wn
6359

H
haowang101779990 已提交
6360 6361 6362 6363
        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
6364

H
haowang101779990 已提交
6365 6366 6367 6368
        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
6369

H
haowang101779990 已提交
6370 6371 6372 6373
        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
6374

H
haowang101779990 已提交
6375 6376
        output = wn * d_e * d_s + en * d_w * d_s
               + ws * d_e * d_n + es * d_w * d_n
D
dengkaipeng 已提交
6377 6378

    Args:
K
Kaipeng Deng 已提交
6379 6380 6381 6382 6383 6384 6385 6386 6387
        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 已提交
6388 6389

    Returns:
H
haowang101779990 已提交
6390
        Variable: Output of shape [N, C, H, W] data samples input X
K
Kaipeng Deng 已提交
6391 6392
                  using bilnear interpolation based on input grid.
                  The data type is same as input tensor.
6393

H
haowang101779990 已提交
6394 6395 6396 6397
    Examples:

        .. code-block:: python

K
Kaipeng Deng 已提交
6398
            import paddle.fluid as fluid
6399 6400
            import paddle.fluid as fluid
            import paddle
K
Kaipeng Deng 已提交
6401

6402
            paddle.enable_static()
K
Kaipeng Deng 已提交
6403 6404
            # use with affine_grid
            x = fluid.data(name='x', shape=[None, 10, 32, 32], dtype='float32')
K
Kaipeng Deng 已提交
6405 6406
            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 已提交
6407
            out = fluid.layers.grid_sampler(x=x, grid=grid)
6408

D
dengkaipeng 已提交
6409 6410 6411
    """
    helper = LayerHelper("grid_sampler", **locals())

6412
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'grid_sampler')
6413 6414 6415
    check_variable_and_dtype(
        grid, 'grid', ['float32', 'float64'], 'grid_sampler'
    )
D
dengkaipeng 已提交
6416 6417 6418 6419 6420 6421
    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")

6422
    out = helper.create_variable_for_type_inference(x.dtype)
D
dengkaipeng 已提交
6423 6424
    ipts = {'X': x, 'Grid': grid}

6425 6426
    attrs = {'use_cudnn': False} if core.is_compiled_with_rocm() else {}

6427 6428 6429
    helper.append_op(
        type='grid_sampler', inputs=ipts, outputs={'Output': out}, attrs=attrs
    )
6430 6431 6432
    return out


G
gmcather 已提交
6433
def log_loss(input, label, epsilon=1e-4, name=None):
6434
    r"""
6435

G
gmcather 已提交
6436 6437 6438 6439 6440 6441 6442
    **Negative Log Loss Layer**

    This layer accepts input predictions and target label and returns the
    negative log loss.

    .. math::

6443 6444
        Out = -label * \log{(input + \epsilon)}
              - (1 - label) * \log{(1 - input + \epsilon)}
G
gmcather 已提交
6445 6446

    Args:
6447
        input (Tensor|list):  A 2-D tensor with shape [N x 1], where N is the
G
gmcather 已提交
6448
                                batch size. This input is a probability computed
Y
Yibing Liu 已提交
6449
                                by the previous operator. Data type float32.
6450
        label (Tensor|list):  The ground truth which is a 2-D tensor with
6451
                                shape [N x 1], where N is the batch size.
Y
Yibing Liu 已提交
6452 6453
                                Data type float32.
        epsilon (float, optional): A small number for numerical stability. Default 1e-4.
6454
        name(str|None): For detailed information, please refer to
Y
Yibing Liu 已提交
6455
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
G
gmcather 已提交
6456 6457

    Returns:
6458
        Tensor, which shape is [N x 1], data type is float32.
G
gmcather 已提交
6459 6460 6461 6462

    Examples:
        .. code-block:: python

6463 6464 6465 6466 6467 6468
          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 已提交
6469
    """
6470
    return paddle.nn.functional.log_loss(input, label, epsilon, name)
G
gmcather 已提交
6471 6472


6473 6474 6475
def bilinear_tensor_product(
    x, y, size, act=None, name=None, param_attr=None, bias_attr=None
):
6476
    r"""
6477 6478
    :api_attr: Static Graph

Y
Yibing Liu 已提交
6479
    **Bilinear Tensor Product Layer**
Q
Qiao Longfei 已提交
6480

Q
Qiao Longfei 已提交
6481
    This layer performs bilinear tensor product on two inputs.
Q
Qiao Longfei 已提交
6482 6483 6484
    For example:

    .. math::
H
haowang101779990 已提交
6485
       out_{i} = x * W_{i} * {y^\mathrm{T}}, i=0,1,...,size-1
Q
Qiao Longfei 已提交
6486

Q
Qiao Longfei 已提交
6487
    In this formula:
6488 6489
      - :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 已提交
6490
      - :math:`W_{i}`: the i-th learned weight, shape is [M, N].
H
haowang101779990 已提交
6491
      - :math:`out_{i}`: the i-th element of out, shape is [batch_size, size].
Q
Qiao Longfei 已提交
6492 6493 6494
      - :math:`y^\mathrm{T}`: the transpose of :math:`y_{2}`.

    Args:
6495
        x (Variable): 2-D input tensor with shape [batch_size, M]. Data type
Y
Yibing Liu 已提交
6496
            is float32 or float64.
6497
        y (Variable): 2-D input tensor with shape [batch_size, N]. Data type
Y
Yibing Liu 已提交
6498
            should be same as **x**.
Q
Qiao Longfei 已提交
6499
        size (int): The dimension of this layer.
Y
Yibing Liu 已提交
6500
        act (str|None): Activation to be applied to the output of this layer. Default None.
6501
        name(str|None): For detailed information, please refer to
Y
Yibing Liu 已提交
6502
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
6503 6504
        param_attr (ParamAttr|None): To specify the weight parameter attribute.
            Default: None, which means the default weight parameter property is
Y
Yibing Liu 已提交
6505
            used. See usage for details in :ref:`api_fluid_ParamAttr` .
6506 6507
        bias_attr (ParamAttr|None): To specify the bias parameter attribute.
            Default: None, which means the default bias parameter property is
Y
Yibing Liu 已提交
6508
            used. See usage for details in :ref:`api_fluid_ParamAttr` .
Q
Qiao Longfei 已提交
6509
    Returns:
Y
Yibing Liu 已提交
6510
        Variable: A 2-D Tensor of shape [batch_size, size]. Data type is the same as input **x**.
Q
Qiao Longfei 已提交
6511 6512 6513 6514

    Examples:
        .. code-block:: python

6515 6516 6517 6518 6519
            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 已提交
6520 6521
    """
    helper = LayerHelper('bilinear_tensor_product', **locals())
Q
Qiao Longfei 已提交
6522
    dtype = helper.input_dtype('x')
Q
Qiao Longfei 已提交
6523 6524 6525

    param_shape = [size, x.shape[1], y.shape[1]]

6526 6527 6528
    w = helper.create_parameter(
        attr=helper.param_attr, shape=param_shape, dtype=dtype, is_bias=False
    )
6529
    out = helper.create_variable_for_type_inference(dtype=dtype)
Q
Qiao Longfei 已提交
6530 6531 6532 6533

    inputs = {"X": x, "Y": y, "Weight": w}
    if helper.bias_attr:
        bias_size = [1, size]
6534 6535 6536
        bias = helper.create_parameter(
            attr=helper.bias_attr, shape=bias_size, dtype=dtype, is_bias=True
        )
Q
Qiao Longfei 已提交
6537
        inputs["Bias"] = bias
6538 6539 6540
    helper.append_op(
        type="bilinear_tensor_product", inputs=inputs, outputs={"Out": out}
    )
Q
Qiao Longfei 已提交
6541 6542 6543

    # add activation
    return helper.append_activation(out)
C
chengduo 已提交
6544 6545 6546 6547 6548


@templatedoc()
def get_tensor_from_selected_rows(x, name=None):
    """
6549 6550 6551 6552 6553 6554 6555 6556 6557
    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]]

6558
        Output is LoDTensor:
6559 6560 6561 6562 6563 6564
           out.shape = [5, 2]
           out.data = [[1, 1],
                       [2, 2],
                       [2, 2],
                       [3, 3],
                       [6, 6]]
C
chengduo 已提交
6565 6566

    Args:
6567 6568 6569
        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 已提交
6570 6571

    Returns:
6572
        Variable: LoDTensor transformed from SelectedRows. The data type is same with input.
B
bdzhuxiaoning 已提交
6573 6574 6575

    Examples:
        .. code-block:: python
6576

B
bdzhuxiaoning 已提交
6577 6578 6579 6580
            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 已提交
6581 6582
    """

6583 6584 6585 6586 6587
    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 已提交
6588 6589
    helper = LayerHelper('get_tensor_from_selected_rows', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
6590 6591 6592 6593 6594 6595
    helper.append_op(
        type='get_tensor_from_selected_rows',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={},
    )
C
chengduo 已提交
6596
    return out
6597 6598


6599
@templatedoc()
6600
def temporal_shift(x, seg_num, shift_ratio=0.25, name=None, data_format="NCHW"):
6601
    """
6602

6603
    **Temporal Shift Operator**
6604

6605
    ${comment}
6606 6607

    Args:
6608
        x(Tensor): ${x_comment}
6609
        seg_num(int): ${seg_num_comment}
D
dengkaipeng 已提交
6610
        shift_ratio(float): ${shift_ratio_comment}
K
Kaipeng Deng 已提交
6611 6612 6613
        name(str, optional): For detailed information, please refer
                             to :ref:`api_guide_Name`. Usually name is no need to set and
                             None by default.
6614 6615
        data_format(str, optional): Data format that specifies the layout of input.
            It can be "NCHW" or "NHWC". Default: "NCHW".
6616 6617

    Returns:
6618
        out(Tensor): The temporal shifting result is a tensor with the
K
Kaipeng Deng 已提交
6619
        same shape and same data type as the input.
6620 6621 6622 6623 6624 6625 6626

    Raises:
        TypeError: seg_num must be int type.

    Examples:
        .. code-block:: python

6627 6628 6629 6630
            import paddle
            import paddle.nn.functional as F

            input = paddle.randn([6, 4, 2, 2])
6631
            out = F.temporal_shift(x=input, seg_num=2, shift_ratio=0.2)
6632
    """
6633 6634 6635
    return paddle.nn.functional.temporal_shift(
        x, seg_num, shift_ratio, name, data_format
    )
6636 6637


6638
class PyFuncRegistry:
S
sneaxiy 已提交
6639 6640 6641
    _register_funcs = []

    def __init__(self, func):
S
sneaxiy 已提交
6642
        if func is None or not callable(func):
S
sneaxiy 已提交
6643 6644 6645
            raise TypeError('func must be a Python function')

        self._func = func
M
minqiyang 已提交
6646
        # find named args using reflection
6647
        args = inspect.getfullargspec(self._func)
S
sneaxiy 已提交
6648 6649 6650 6651 6652 6653
        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 已提交
6654 6655 6656
        '''
        Why record self here?

M
minqiyang 已提交
6657 6658
        1. For debug usage. Users can call
           :code:`py_func.registered_func(idx)` method
S
sneaxiy 已提交
6659
           to find the registered function corresponding
M
minqiyang 已提交
6660
           to :code:`idx`.
S
sneaxiy 已提交
6661

M
minqiyang 已提交
6662 6663
        2. For increasing reference count of self.
           It seems that to release Python object
S
sneaxiy 已提交
6664
           whose reference count is 1 would cause
M
minqiyang 已提交
6665
           segmentation fault error in C++ side.
S
sneaxiy 已提交
6666 6667
           May be lack of Python GC in C++ side?
        '''
S
sneaxiy 已提交
6668
        PyFuncRegistry._register_funcs.append(self)
S
sneaxiy 已提交
6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682

    @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 已提交
6683 6684 6685 6686 6687 6688 6689 6690 6691
        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 已提交
6692

S
sneaxiy 已提交
6693
        if not isinstance(func_ret, (list, tuple)):
6694
            func_ret = (func_ret,)
S
sneaxiy 已提交
6695 6696

        ret = []
S
sneaxiy 已提交
6697 6698 6699
        for each_ret in func_ret:
            if each_ret is None or isinstance(each_ret, core.LoDTensor):
                ret.append(each_ret)
S
sneaxiy 已提交
6700 6701
                continue

S
sneaxiy 已提交
6702 6703
            if not isinstance(each_ret, np.ndarray):
                each_ret = np.array(each_ret)
S
sneaxiy 已提交
6704

S
sneaxiy 已提交
6705 6706 6707
            tensor = core.LoDTensor()
            tensor.set(each_ret, core.CPUPlace())
            ret.append(tensor)
S
sneaxiy 已提交
6708

S
sneaxiy 已提交
6709
        return tuple(ret)
S
sneaxiy 已提交
6710 6711


6712
@static_only
S
sneaxiy 已提交
6713 6714 6715
@templatedoc()
def py_func(func, x, out, backward_func=None, skip_vars_in_backward_input=None):
    """
6716 6717
    :api_attr: Static Graph

6718 6719
    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
6720 6721
    other easily. So you can use Python and numpy API to register a python OP.

6722 6723
    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
6724
    call ``backward_func`` at backward runtime(if ``backward_func`` is not  None).
6725 6726
    ``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.
6727

6728
    The input of the backward function ``backward_func`` is ``x``, ``out`` and
6729 6730 6731
    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``.
6732

6733 6734
    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
6735 6736 6737 6738 6739 6740 6741
    ``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
6742 6743
            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
6744
            actively convert Tensor into a numpy array, so that we can use Python and
6745
            numpy API arbitrarily. If not, some operations of numpy may not be compatible.
6746 6747 6748 6749 6750 6751 6752
        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.
6753 6754 6755
        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
6756
            ``x`` when the network is at backward runtime.
6757 6758
        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].
6759
            It must belong to either ``x`` or ``out``. The default  value is None, which means
6760 6761
            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
6762
            useful when ``backward_func`` is not None.
6763 6764

    Returns:
6765
        Tensor|tuple(Tensor)|list[Tensor]: The output ``out`` of the forward function ``func``.
S
sneaxiy 已提交
6766 6767

    Examples:
6768
        .. code-block:: python
6769

6770
            # example 1:
6771
            import paddle
6772
            import numpy as np
6773

6774 6775 6776
            paddle.enable_static()

            # Creates a forward function, Tensor can be input directly without
6777
            # being converted into numpy array.
6778 6779 6780
            def tanh(x):
                return np.tanh(x)

6781
            # Skip x in backward function and return the gradient of x
6782
            # Tensor must be actively converted to numpy array, otherwise,
6783
            # operations such as +/- can't be used.
6784 6785
            def tanh_grad(y, dy):
                return np.array(dy) * (1 - np.square(np.array(y)))
6786

6787
            # Creates a forward function for debugging running networks(print value)
6788 6789
            def debug_func(x):
                print(x)
6790

6791
            def create_tmp_var(name, dtype, shape):
6792
                return paddle.static.default_main_program().current_block().create_var(
6793
                    name=name, dtype=dtype, shape=shape)
6794 6795 6796

            def simple_net(img, label):
                hidden = img
6797
                for idx in range(4):
6798
                    hidden = paddle.static.nn.fc(hidden, size=200)
6799 6800 6801
                    new_hidden = create_tmp_var(name='hidden_{}'.format(idx),
                        dtype=hidden.dtype, shape=hidden.shape)

6802
                    # User-defined forward and backward
6803
                    hidden = paddle.static.py_func(func=tanh, x=hidden,
6804 6805 6806
                        out=new_hidden, backward_func=tanh_grad,
                        skip_vars_in_backward_input=hidden)

6807
                    # User-defined debug functions that print out the input Tensor
6808
                    paddle.static.py_func(func=debug_func, x=hidden, out=None)
6809

6810
                prediction = paddle.static.nn.fc(hidden, size=10, activation='softmax')
6811 6812 6813 6814
                ce_loss = paddle.nn.loss.CrossEntropyLoss()
                return ce_loss(prediction, label)

            x = paddle.static.data(name='x', shape=[1,4], dtype='float32')
6815
            y = paddle.static.data(name='y', shape=[1], dtype='int64')
6816 6817 6818 6819 6820
            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')
6821
            input2 = np.random.randint(1, 10, size=[1], dtype='int64')
6822 6823 6824 6825 6826 6827
            out = exe.run(paddle.static.default_main_program(),
                          feed={'x':input1, 'y':input2},
                          fetch_list=[res.name])
            print(out)

        .. code-block:: python
6828

6829
            # example 2:
6830
            # This example shows how to turn Tensor into numpy array and
6831
            # use numpy API to register an Python OP
6832
            import paddle
6833 6834
            import numpy as np

6835 6836
            paddle.enable_static()

6837
            def element_wise_add(x, y):
6838
                # Tensor must be actively converted to numpy array, otherwise,
6839
                # numpy.shape can't be used.
6840
                x = np.array(x)
6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853
                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):
6854
                return paddle.static.default_main_program().current_block().create_var(
6855 6856 6857
                            name=name, dtype=dtype, shape=shape)

            def py_func_demo():
6858 6859
                start_program = paddle.static.default_startup_program()
                main_program = paddle.static.default_main_program()
6860 6861

                # Input of the forward function
6862 6863
                x = paddle.static.data(name='x', shape=[2,3], dtype='int32')
                y = paddle.static.data(name='y', shape=[2,3], dtype='int32')
6864

6865 6866 6867 6868
                # 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]
6869
                paddle.static.py_func(func=element_wise_add, x=[x,y], out=output)
6870

6871
                exe=paddle.static.Executor(paddle.CPUPlace())
6872 6873 6874 6875 6876
                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')
6877
                out = exe.run(main_program,
6878 6879 6880 6881 6882 6883 6884 6885 6886
                            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 已提交
6887
    """
S
sneaxiy 已提交
6888
    helper = LayerHelper('py_func', **locals())
6889
    check_type(x, 'X', (list, tuple, Variable, type(None)), 'py_func')
S
sneaxiy 已提交
6890 6891 6892
    if x is None:
        x = []
    elif isinstance(x, Variable):
S
sneaxiy 已提交
6893
        x = [x]
6894 6895 6896
    elif isinstance(x, tuple):
        x = list(x)
    elif not isinstance(x, (list, tuple, Variable)):
S
sneaxiy 已提交
6897
        raise TypeError('Input must be Variable/list(Variable)/tuple(Variable)')
6898
    check_type(out, 'Out', (list, tuple, Variable, type(None)), 'py_func')
S
sneaxiy 已提交
6899 6900 6901
    if out is None:
        out_list = []
    elif isinstance(out, Variable):
S
sneaxiy 已提交
6902
        out_list = [out]
6903 6904
    elif isinstance(out, tuple):
        out_list = list(out)
6905 6906 6907
    elif isinstance(out, list):
        out_list = out
    else:
S
sneaxiy 已提交
6908
        raise TypeError(
6909 6910
            'Output must be Variable/list(Variable)/tuple(Variable)'
        )
S
sneaxiy 已提交
6911

S
sneaxiy 已提交
6912
    fwd_func_id = PyFuncRegistry(func).id
6913 6914 6915
    bwd_func_id = (
        PyFuncRegistry(backward_func).id if backward_func is not None else -1
    )
S
sneaxiy 已提交
6916 6917

    for each_out in out_list:
S
sneaxiy 已提交
6918 6919
        if len(each_out.shape) == 0:
            raise ValueError(
S
sneaxiy 已提交
6920 6921
                'Output shapes of py_func op should be provided by users manually'
            )
S
sneaxiy 已提交
6922

S
sneaxiy 已提交
6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934
    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(
6935 6936 6937 6938
                    'Variable {} is not found in forward inputs and outputs'.format(
                        v.name
                    )
                )
S
sneaxiy 已提交
6939
            backward_skip_vars.add(v.name)
S
sneaxiy 已提交
6940

6941 6942 6943 6944 6945 6946 6947 6948 6949 6950
    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 已提交
6951
    return out
S
sneaxiy 已提交
6952 6953 6954


# For debug usage
S
sneaxiy 已提交
6955 6956 6957 6958
py_func.registered_func = PyFuncRegistry.registered_func
py_func.registered_func_num = PyFuncRegistry.registered_func_num


H
heqiaozhi 已提交
6959
def continuous_value_model(input, cvm, use_cvm=True):
6960
    r"""
H
fix doc  
heqiaozhi 已提交
6961

H
heqiaozhi 已提交
6962
    **continuous_value_model layers**
H
fix doc  
heqiaozhi 已提交
6963

Z
zhoushiyu 已提交
6964
    Now, this OP is used in CTR project to remove or dispose show and click value in :attr:`input`.
H
fix doc  
heqiaozhi 已提交
6965

Z
zhoushiyu 已提交
6966 6967
    :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 已提交
6968
    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 已提交
6969 6970
    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 已提交
6971

Z
zhoushiyu 已提交
6972 6973 6974 6975 6976 6977 6978
    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 已提交
6979

H
heqiaozhi 已提交
6980
    Returns:
H
fix doc  
heqiaozhi 已提交
6981

Z
zhoushiyu 已提交
6982 6983
        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 已提交
6984

H
heqiaozhi 已提交
6985
    Examples:
H
fix doc  
heqiaozhi 已提交
6986

H
heqiaozhi 已提交
6987
        .. code-block:: python
H
fix doc  
heqiaozhi 已提交
6988

6989
          import paddle.fluid as fluid
Z
zhoushiyu 已提交
6990 6991
          input = fluid.data(name="input", shape=[64, 1], dtype="int64")
          label = fluid.data(name="label", shape=[64, 1], dtype="int64")
H
heqiaozhi 已提交
6992 6993 6994 6995 6996 6997 6998 6999
          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 已提交
7000

H
heqiaozhi 已提交
7001 7002 7003
    """
    helper = LayerHelper('cvm', **locals())
    out = helper.create_variable(dtype=input.dtype)
7004 7005 7006 7007 7008 7009 7010 7011 7012
    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 已提交
7013
    return out
Z
zhoukunsheng 已提交
7014 7015


7016
def unfold(x, kernel_sizes, strides=1, paddings=0, dilations=1, name=None):
7017
    r"""
7018

S
SunGaofeng 已提交
7019
    This op returns a col buffer of sliding local blocks of input x, also known
7020
    as im2col for batched 2D image tensors. For each block under the convolution filter,
T
tianshuo78520a 已提交
7021
    all element will be rearranged as a column. While the convolution filter sliding over
7022 7023
    the input feature map, a series of such columns will be formed.

S
SunGaofeng 已提交
7024
    For each input :math:`x` with shape [N, C, H, W], the output shape [N, Cout, Lout]
7025 7026 7027 7028
    can be calculated as following.

    .. math::

7029
        dkernel[0] &= dilations[0] \times (kernel\_sizes[0] - 1) + 1
7030

7031
        dkernel[1] &= dilations[1] \times (kernel\_sizes[1] - 1) + 1
7032

7033
        hout &= \frac{H + paddings[0] + paddings[2] - dkernel[0]}{strides[0]} + 1
7034

7035
        wout &= \frac{W + paddings[1] + paddings[3] - dkernel[1]}{strides[1]} + 1
7036

7037
        Cout &= C \times kernel\_sizes[0] \times kernel\_sizes[1]
7038

7039
        Lout &= hout \times wout
7040 7041


S
SunGaofeng 已提交
7042
    Parameters:
7043
        x(Tensor):              4-D Tensor, input tensor of format [N, C, H, W],
S
SunGaofeng 已提交
7044
                                  data type can be float32 or float64
7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056
        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 已提交
7057
        dilations(int|list):      the dilations of convolution kernel, should be
T
tianshuo78520a 已提交
7058
                                  [dilation_h, dilation_w], or an integer dilation treated as
7059
                                  [dilation, dilation]. For default, it will be [1, 1].
7060 7061
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
7062
                             For more information, please refer to :ref:`api_guide_Name`
7063

7064

7065
    Returns:
7066
        The tensor corresponding to the sliding local blocks.
7067 7068 7069
        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 已提交
7070 7071 7072
        The data type of output is the same as the input :math:`x`

    Return Type:
7073
        Tensor
7074 7075 7076 7077 7078

    Examples:

        .. code-block:: python

7079 7080 7081 7082 7083
            import paddle
            import paddle.nn.functional as F

            x = paddle.randn((100,3,224,224))
            y = F.unfold(x, [3, 3], 1, 1, 1)
7084 7085
    """

7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105
    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,
):
7106
    r"""
7107

7108
    Deformable ROI Pooling Layer
7109

7110
    Performs deformable region-of-interest pooling on inputs. As described
7111
    in `Deformable Convolutional Networks <https://arxiv.org/abs/1703.06211>`_, it will get offset for each bin after
7112
    roi pooling so that pooling at correct region. Batch_size will change to the number of region bounding boxes after deformable_roi_pooling.
7113

7114
    The operation has three steps:
7115

7116
    1. Dividing each region proposal into equal-sized sections with the pooled_width and pooled_height.
7117

7118 7119
    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.
7120

7121
    3. Sample several points in each bin to get average values as output.
7122 7123


7124 7125 7126 7127 7128 7129 7130 7131 7132
    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.
7133 7134 7135
        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.
7136 7137 7138 7139
        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.
7140
        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
7141
                          is k1 * k2 * (C + 1), which k1 and k2 are group width and height and C+1 is number of output
T
tianshuo78520a 已提交
7142
                          channels.) eg.(4, 6), which 4 is height of group and 6 is width of group. Default: [1, 1].
7143 7144 7145 7146 7147 7148 7149
        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 已提交
7150
                                   If value is True, input dimension should be output dimension * pooled_height * pooled_width. Default: False.
7151 7152 7153 7154
        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 已提交
7155 7156 7157 7158

    Examples:
      .. code-block:: python

7159 7160
        # position_sensitive=True
        import paddle.fluid as fluid
C
chengjuntao 已提交
7161
        input = fluid.data(name="input",
7162 7163
                           shape=[2, 192, 64, 64],
                           dtype='float32')
C
chengjuntao 已提交
7164 7165
        rois = fluid.data(name="rois",
                          shape=[-1, 4],
7166
                          dtype='float32',
C
chengjuntao 已提交
7167 7168
                          lod_level=1)
        trans = fluid.data(name="trans",
7169 7170 7171 7172 7173
                           shape=[2, 384, 64, 64],
                           dtype='float32')
        x = fluid.layers.deformable_roi_pooling(input=input,
                                                rois=rois,
                                                trans=trans,
C
chengjuntao 已提交
7174
                                                no_trans=False,
7175
                                                spatial_scale=1.0,
C
chengjuntao 已提交
7176 7177 7178 7179
                                                group_size=(1, 1),
                                                pooled_height=8,
                                                pooled_width=8,
                                                part_size=(8, 8),
7180
                                                sample_per_part=4,
C
chengjuntao 已提交
7181 7182
                                                trans_std=0.1,
                                                position_sensitive=True)
7183

7184
        # position_sensitive=False
7185
        import paddle.fluid as fluid
C
chengjuntao 已提交
7186
        input = fluid.data(name="input",
7187 7188
                           shape=[2, 192, 64, 64],
                           dtype='float32')
C
chengjuntao 已提交
7189 7190
        rois = fluid.data(name="rois",
                          shape=[-1, 4],
7191
                          dtype='float32',
C
chengjuntao 已提交
7192 7193
                          lod_level=1)
        trans = fluid.data(name="trans",
7194 7195 7196 7197 7198
                           shape=[2, 384, 64, 64],
                           dtype='float32')
        x = fluid.layers.deformable_roi_pooling(input=input,
                                                rois=rois,
                                                trans=trans,
C
chengjuntao 已提交
7199
                                                no_trans=False,
7200
                                                spatial_scale=1.0,
C
chengjuntao 已提交
7201 7202 7203 7204
                                                group_size=(1, 1),
                                                pooled_height=8,
                                                pooled_width=8,
                                                part_size=(8, 8),
7205
                                                sample_per_part=4,
C
chengjuntao 已提交
7206 7207
                                                trans_std=0.1,
                                                position_sensitive=False)
C
cjt222 已提交
7208 7209
    """

7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221
    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'
    )
7222
    if part_size is not None:
7223 7224 7225
        check_type(
            part_size, 'part_size', (list, tuple), 'deformable_roi_pooling'
        )
7226

C
cjt222 已提交
7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242
    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')
7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258
    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 已提交
7259
    return output
7260 7261


7262
@deprecated(since="2.0.0", update_to="paddle.shard_index")
7263 7264
def shard_index(input, index_num, nshards, shard_id, ignore_value=-1):
    """
L
lilong12 已提交
7265 7266 7267 7268 7269 7270 7271 7272 7273
    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).
7274 7275
    ::

7276
        shard_size = (index_num + nshards - 1) // nshards
7277

L
lilong12 已提交
7278 7279 7280
    For each value `v` in `input`, we reset it to a new value according to the
    following formula:
    ::
7281

L
lilong12 已提交
7282 7283 7284 7285
        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`.
7286 7287

    Args:
L
lilong12 已提交
7288 7289
        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`.
7290 7291 7292
        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.
7293 7294

    Returns:
L
lilong12 已提交
7295
        Tensor.
7296 7297 7298 7299

    Examples:
        .. code-block:: python

7300 7301 7302 7303 7304 7305 7306 7307
            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]]
7308
    """
H
hong 已提交
7309
    if in_dygraph_mode():
7310 7311 7312
        return _C_ops.shard_index(
            input, index_num, nshards, shard_id, ignore_value
        )
H
hong 已提交
7313

B
Baibaifan 已提交
7314
    check_variable_and_dtype(input, 'input', ['int64', 'int32'], 'shard_index')
7315 7316 7317
    op_type = 'shard_index'
    helper = LayerHelper(op_type, **locals())
    if shard_id < 0 or shard_id >= nshards:
7318 7319 7320
        raise ValueError(
            'The shard_id(%d) should be in [0, %d)' % (shard_id, nshards)
        )
7321 7322

    out = helper.create_variable_for_type_inference(dtype=input.dtype)
7323 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334
    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,
    )
7335
    return out
H
huangjun12 已提交
7336 7337 7338 7339


@templatedoc()
def hard_swish(x, threshold=6.0, scale=6.0, offset=3.0, name=None):
7340
    r"""
7341 7342 7343
    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 已提交
7344

7345
    The formula is as follows:
H
huangjun12 已提交
7346

7347
    .. math::
H
huangjun12 已提交
7348

7349
        out = \\frac{x * (min(max(0, x+offset), threshold))}{scale}
H
huangjun12 已提交
7350

7351 7352 7353 7354 7355 7356 7357 7358 7359
    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
7360 7361
        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`

7362 7363
    Returns:
        Variable: The output tensor with the same shape and data type as input.
7364 7365


7366
    Examples:
7367

7368
    .. code-block:: python
7369

7370
        import paddle.fluid as fluid
7371
        import paddle
7372
        import numpy as np
7373
        paddle.enable_static()
7374

7375
        DATATYPE='float32'
7376

7377
        x_data = np.array([i for i in range(1,5)]).reshape([1,1,4]).astype(DATATYPE)
7378

7379 7380
        x = fluid.data(name="x", shape=[None,1,4], dtype=DATATYPE)
        y = fluid.layers.hard_swish(x)
7381

7382 7383 7384 7385 7386
        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 已提交
7387
    """
J
Jiabin Yang 已提交
7388
    if _non_static_mode():
7389 7390 7391
        return _legacy_C_ops.hard_swish(
            x, 'threshold', threshold, 'scale', scale, 'offset', offset
        )
7392

7393 7394 7395
    check_variable_and_dtype(
        x, 'x', ['float16', 'float32', 'float64'], 'hard_swish'
    )
7396

H
huangjun12 已提交
7397 7398
    helper = LayerHelper('hard_swish', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
7399 7400 7401 7402 7403 7404
    helper.append_op(
        type='hard_swish',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'threshold': threshold, 'scale': scale, 'offset': offset},
    )
H
huangjun12 已提交
7405
    return out
R
ruri 已提交
7406 7407


K
Kaipeng Deng 已提交
7408 7409
@templatedoc()
def mish(x, threshold=20, name=None):
7410
    r"""
K
Kaipeng Deng 已提交
7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467
    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.]]
    """
7468
    if in_dygraph_mode():
7469
        return _C_ops.mish(x, threshold)
7470
    if _in_legacy_dygraph():
7471
        return _legacy_C_ops.mish(x, 'threshold', threshold)
7472

K
Kaipeng Deng 已提交
7473 7474
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'mish')
    check_type(threshold, 'threshold', (float, int), 'mish')
7475 7476 7477 7478 7479
    assert (
        threshold > 0
    ), "threshold of mish should be greater than 0, " "but got {}".format(
        threshold
    )
K
Kaipeng Deng 已提交
7480 7481 7482

    helper = LayerHelper('mish', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
7483 7484 7485 7486 7487 7488
    helper.append_op(
        type='mish',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'threshold': threshold},
    )
K
Kaipeng Deng 已提交
7489 7490 7491
    return out


7492
@deprecated(since="2.0.0", update_to="paddle.uniform")
7493
@templatedoc()
7494 7495 7496
def uniform_random(
    shape, dtype='float32', min=-1.0, max=1.0, seed=0, name=None
):
7497
    """
7498 7499
    This OP returns a Tensor filled with random values sampled from a uniform
    distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.
7500 7501 7502

    Examples:
    ::
7503

7504 7505
        Input:
          shape = [1, 2]
7506

7507 7508 7509 7510
        Output:
          result=[[0.8505902, 0.8397286]]

    Args:
7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523
        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
7524 7525
            use a seed generated by the system. Note that if seed is not 0,
            this operator will always generate the same random numbers every
7526
            time. Default is 0.
7527 7528 7529
        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`.
7530

7531
    Returns:
7532 7533
        Tensor: A Tensor filled with random values sampled from a uniform
        distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.
7534

7535
    Raises:
7536 7537
        TypeError: If ``shape`` is not list, tuple, Tensor.
        TypeError: If ``dtype`` is not float32, float64.
7538

7539 7540 7541
    Examples:
        .. code-block:: python

7542
            import paddle
7543
            import paddle.fluid as fluid
7544
            paddle.enable_static()
7545 7546

            # example 1:
7547
            # attr shape is a list which doesn't contain Tensor.
7548
            result_1 = fluid.layers.uniform_random(shape=[3, 4])
7549 7550 7551
            # [[ 0.84524226,  0.6921872,   0.56528175,  0.71690357],
            #  [-0.34646994, -0.45116323, -0.09902662, -0.11397249],
            #  [ 0.433519,    0.39483607, -0.8660099,   0.83664286]]
7552 7553

            # example 2:
7554 7555 7556
            # 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)
7557
            result_2 = fluid.layers.uniform_random(shape=[dim_1, dim_2])
7558 7559
            # [[-0.9951253,   0.30757582, 0.9899647 ],
            #  [ 0.5864527,   0.6607096,  -0.8886161 ]]
7560 7561

            # example 3:
7562
            # attr shape is a Tensor, the data type must be int64 or int32.
7563
            var_shape = fluid.data(name='var_shape', shape=[2], dtype="int64")
7564
            result_3 = fluid.layers.uniform_random(var_shape)
7565 7566 7567 7568
            # if var_shape's value is [2, 3]
            # result_3 is:
            # [[-0.8517412,  -0.4006908,   0.2551912 ],
            #  [ 0.3364414,   0.36278176, -0.16085452]]
7569

7570 7571 7572
    """
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
7573

7574 7575
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
7576
        return _C_ops.uniform(
7577 7578 7579 7580 7581 7582 7583
            shape,
            dtype,
            float(min),
            float(max),
            seed,
            _current_expected_place(),
        )
7584
    elif _in_legacy_dygraph():
7585
        shape = utils.convert_shape_to_list(shape)
7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597
        return _legacy_C_ops.uniform_random(
            'shape',
            shape,
            'min',
            float(min),
            'max',
            float(max),
            'seed',
            seed,
            'dtype',
            dtype,
        )
7598

7599
    check_type(shape, 'shape', (list, tuple, Variable), 'uniform_random/rand')
7600 7601 7602
    check_dtype(
        dtype, 'dtype', ('float32', 'float64', 'uint16'), 'uniform_random/rand'
    )
7603 7604
    check_type(min, 'min', (float, int, Variable), 'uniform_random/rand')
    check_type(max, 'max', (float, int, Variable), 'uniform_random/rand')
7605 7606

    inputs = dict()
7607
    attrs = {'seed': seed, 'min': min, 'max': max, 'dtype': dtype}
7608 7609 7610
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='uniform_random/rand'
    )
7611

7612
    helper = LayerHelper("uniform_random", **locals())
7613
    out = helper.create_variable_for_type_inference(dtype)
7614 7615 7616
    helper.append_op(
        type="uniform_random", inputs=inputs, attrs=attrs, outputs={"Out": out}
    )
7617
    utils.try_set_static_shape_tensor(out, shape)
7618
    return out
myq406450149's avatar
myq406450149 已提交
7619 7620 7621 7622 7623 7624 7625


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

myq406450149's avatar
myq406450149 已提交
7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651
        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()
7652 7653 7654
    check_dtype(
        dtype, 'unbind', ['float32', 'float64', 'int32', 'int64'], 'unbind'
    )
myq406450149's avatar
myq406450149 已提交
7655
    if not isinstance(axis, (int)):
7656 7657 7658
        raise TypeError(
            "The type of 'axis'  must be int, but received %s." % (type(axis))
        )
myq406450149's avatar
myq406450149 已提交
7659 7660 7661 7662 7663 7664 7665 7666 7667 7668
    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)
    ]

7669 7670 7671 7672 7673 7674
    helper.append_op(
        type="unbind",
        inputs={"X": input},
        outputs={"Out": outs},
        attrs={"axis": axis},
    )
myq406450149's avatar
myq406450149 已提交
7675
    return outs