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

import numpy as np

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

Y
Yu Yang 已提交
64 65

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

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

Y
Yu Yang 已提交
153

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

    return reduce_all, dim


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

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

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

218
    **Fully Connected Layer**
Y
Yu Yang 已提交
219

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

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

233 234 235 236
    .. math::

        Out = Act({XW + b})

237
    When the input is a list of Tensor(or LoDTensor):
238 239 240

    .. math::

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

    In the above equation:

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

    .. code-block:: text

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

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

    Examples:
        .. code-block:: python

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

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

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

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


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

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

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

416 417 418 419
                        [[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.
420

421
        Case 2:
422

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

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

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

470 471
    Examples:
        .. code-block:: python
Y
Yu Yang 已提交
472

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

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

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

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

    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

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


537 538 539 540 541 542 543 544 545 546 547
def _pull_sparse(
    input,
    size,
    table_id,
    accessor_class,
    name="embedding",
    ctr_label_name="",
    padding_id=0,
    dtype='float32',
    scale_sparse_grad=True,
):
548
    r"""
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
    **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
594
        'is_distributed': True,
595 596
    }
    # this is only for compatible with embedding op
597 598 599 600 601 602 603 604 605
    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,
    )
606 607 608 609 610
    if len(outs) == 1:
        return outs[0]
    return outs


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


685 686 687
def _pull_gpups_sparse(
    input, size, dtype='float32', is_distributed=False, is_sparse=False
):
Y
yaoxuefeng 已提交
688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
    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(
721 722 723
            "GpuPS only support float type embedding now, and your type is: "
            + dtype
        )
Y
yaoxuefeng 已提交
724 725 726 727 728 729
    helper.input_dtype()
    inputs = helper.multiple_input()
    outs = [
        helper.create_variable_for_type_inference(dtype)
        for i in range(len(inputs))
    ]
730 731 732 733 734 735 736 737 738 739 740 741 742
    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 已提交
743
    if len(outs) == 1:
744 745 746 747
        return outs[0]
    return outs


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


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

Y
yuyang18 已提交
812 813 814 815 816
    Linear Chain CRF.

    ${comment}

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

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

J
JesseyXujin 已提交
827 828 829
    Examples:
        .. code-block:: python

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

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

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

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

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

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

    return log_likelihood


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

W
wopeizl 已提交
946
    ${comment}
Y
yi.wu 已提交
947

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

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

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

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

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

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

965 966
           import paddle
           paddle.enable_static()
967 968 969

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

974 975 976 977
           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"))
978 979 980

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

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

W
wopeizl 已提交
1009
    return viterbi_path
Y
Yu Yang 已提交
1010 1011


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

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

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

    Examples:
        .. code-block:: python

N
Noel 已提交
1027 1028 1029 1030 1031 1032 1033
            import paddle

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

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


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

1060 1061 1062 1063
    Computes dropout.

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

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

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

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

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

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

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

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

M
minqiyang 已提交
1098

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

    Examples:
1103

1104 1105
        .. code-block:: python

1106
            import paddle
1107
            import paddle.fluid as fluid
1108

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

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

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

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

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

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


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

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

1189 1190 1191 1192 1193 1194 1195
    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.
1196

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

1200 1201 1202 1203 1204
    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.
1205

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

1208
    .. math::
1209

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

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

    .. 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],
1257
                         [0.72747516, 0.72747516, 0.72747516, 0.72747516]]]
1258

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

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

    Examples:

        .. code-block:: python

N
Noel 已提交
1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292
            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 已提交
1293 1294

    """
1295

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

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

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

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

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


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

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

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

C
chengduoZH 已提交
1358 1359
    .. math::

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

T
tensor-tang 已提交
1362
    Where:
C
chengduoZH 已提交
1363

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

    Example:

1373 1374
        - Input:

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

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

1379
        - Output:
T
tensor-tang 已提交
1380

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

C
chengduoZH 已提交
1383
        Where
1384 1385

        .. math::
C
chengduoZH 已提交
1386

W
weixing02 已提交
1387 1388
            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 已提交
1389 1390

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

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

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

1465 1466
          import paddle
          paddle.enable_static()
1467

1468 1469 1470
          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 已提交
1471 1472
    """

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

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

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

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

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

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

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

1541 1542 1543
    helper = LayerHelper(l_type, **locals())
    dtype = helper.input_dtype()

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

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

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

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

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

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

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

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

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

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

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

    return helper.append_activation(pre_act)


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

F
fengjiayi 已提交
1672
    ${comment}
1673 1674

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

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

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

    Examples:

        .. code-block:: python

1728
          import paddle.fluid as fluid
1729 1730 1731
          import paddle

          paddle.enable_static()
1732

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

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

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

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

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

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

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

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

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

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

    return pool_out


D
dengkaipeng 已提交
1899
@templatedoc()
1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912
def pool3d(
    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="NCDHW",
):
1913
    """
1914

1915
    ${comment}
1916 1917

    Args:
K
Kaipeng Deng 已提交
1918 1919
        input (Variable): The input tensor of pooling operator, which is a 5-D tensor with
                          shape [N, C, D, H, W]. The format of
1920 1921 1922
                          input tensor is `"NCDHW"` or `"NDHWC"`, where `N` is batch size, `C` is
                          the number of channels, `D` is the depth of the feature,
                          `H` is the height of the feature, and `W` is the width
D
dengkaipeng 已提交
1923
                          of the feature.
1924 1925
        pool_size (int|list|tuple): The pool kernel size. If pool kernel size
            is a tuple or list, it must contain three integers,
D
dengkaipeng 已提交
1926 1927 1928
            (pool_size_Depth, pool_size_Height, pool_size_Width).
            Otherwise, the pool kernel size will be the cube of an int.
        pool_type (string): ${pooling_type_comment}
1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939
        pool_stride (string|int|list|tuple)): The pool padding. If `pool_padding` is a string, either 'VALID' or
            'SAME' which is the padding algorithm. If pool stride size is a tuple or list,
            it must contain three integers, `[stride_Depth, stride_Height, stride_Width]`.
            Otherwise, the pool stride size will be a cube of an int.
        pool_padding (int|list|tuple): The pool padding size. If pool padding size is a tuple or list,
            it could be in three forms: `[pad_depth, pad_height, pad_width]` or
            `[pad_depth_front, pad_depth_back, pad_height_top, pad_height_bottom, pad_width_left, pad_width_right]`,
            and when `data_format` is `"NCDHW"`, `pool_padding` can be in the form
            `[[0,0], [0,0], [pad_depth_front, pad_depth_back], [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right]]`.
            when `data_format` is `"NDHWC"`, `pool_padding` can be in the form
            `[[0,0], [pad_depth_front, pad_depth_back], [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right], [0,0]]`.
1940 1941 1942
        global_pooling (bool): ${global_pooling_comment}
        use_cudnn (bool): ${use_cudnn_comment}
        ceil_mode (bool): ${ceil_mode_comment}
K
Kaipeng Deng 已提交
1943 1944 1945
        name(str, optional): For detailed information, please refer
                             to :ref:`api_guide_Name`. Usually name is no need to set and
                             None by default.
1946
        exclusive (bool): Whether to exclude padding points in average pooling
1947 1948 1949 1950
                          mode, default is true.
        data_format (string): The data format of the input and output data. 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]`.
1951

1952
    Returns:
K
Kaipeng Deng 已提交
1953
        Variable: The output tensor of pooling result. The data type is same as input tensor.
D
dengkaipeng 已提交
1954

1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967
    Raises:
        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 "NCDHW" or "NDHWC".
        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.

D
dengkaipeng 已提交
1968 1969 1970 1971
    Examples:

        .. code-block:: python

1972
          import paddle.fluid as fluid
1973 1974 1975
          import paddle

          paddle.enable_static()
1976

K
Kaipeng Deng 已提交
1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001
          data = fluid.data(name='data', shape=[None, 3, 32, 32, 32], dtype='float32')

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

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

          # global average pool3d
          pool3d = fluid.layers.pool3d(
            input = data,
            pool_size = 2,
            pool_type = "avg",
            pool_stride = 1,
            global_pooling=True)
2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024

          # example 1:
          # Attr(pool_padding) is a list with 6 elements, Attr(data_format) is "NCDHW".
          out_1 = fluid.layers.pool3d(
            input = data,
            pool_size = 2,
            pool_type = "avg",
            pool_stride = 1,
            pool_padding = [1, 2, 1, 0, 1, 2],
            global_pooling = False,
            data_format = "NCDHW")

          # example 2:
          # Attr(pool_padding) is a string, Attr(data_format) is "NCDHW".
          out_2 = fluid.layers.pool3d(
            input = data,
            pool_size = 3,
            pool_type = "avg",
            pool_stride = 1,
            pool_padding = "VALID",
            global_pooling = False,
            data_format = "NCDHW")

Y
Yu Yang 已提交
2025 2026 2027
    """
    if pool_type not in ["max", "avg"]:
        raise ValueError(
2028
            "Unknown Attr(pool_type): '%s'. It can only be 'max' or 'avg'.",
2029 2030
            str(pool_type),
        )
C
chengduoZH 已提交
2031

C
chengduoZH 已提交
2032 2033
    if global_pooling is False and pool_size == -1:
        raise ValueError(
2034
            "When Attr(global_pooling) is False, Attr(pool_size) must be passed "
2035 2036 2037
            "and be a valid value. Received Attr(pool_size): %s."
            % str(pool_size)
        )
2038 2039

    if not isinstance(use_cudnn, bool):
2040 2041 2042 2043
        raise TypeError(
            "Attr(use_cudnn) should be True or False. Received "
            "Attr(use_cudnn): %s. " % str(use_cudnn)
        )
2044 2045 2046 2047

    if data_format not in ["NCDHW", "NDHWC"]:
        raise ValueError(
            "Attr(data_format) should be 'NCDHW' or 'NDHWC'. Received "
2048 2049
            "Attr(data_format): %s" % str(data_format)
        )
C
chengduoZH 已提交
2050

2051 2052
    pool_size = utils.convert_to_list(pool_size, 3, 'pool_size')
    pool_stride = utils.convert_to_list(pool_stride, 3, 'pool_stride')
C
chengduoZH 已提交
2053

2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064
    def update_padding(padding, data_format):
        def is_list_or_tuple(ele):
            if isinstance(ele, (list, tuple)):
                return True
            return False

        if is_list_or_tuple(padding) and len(padding) == 5:
            if is_list_or_tuple(padding[0]) and (data_format == "NCDHW"):
                if not (padding[0] == [0, 0] and padding[1] == [0, 0]):
                    raise ValueError(
                        "Non-zero pool_padding(%s) in the batch or channel dimensions "
2065 2066
                        "is not supported." % str(padding)
                    )
2067 2068 2069 2070 2071 2072
                padding = padding[2:5]
                padding = [ele for a_list in padding for ele in a_list]
            elif is_list_or_tuple(padding[0]) and (data_format == "NDHWC"):
                if not (padding[0] == [0, 0] and padding[4] == [0, 0]):
                    raise ValueError(
                        "Non-zero pool_padding(%s) in the batch or channel dimensions "
2073 2074
                        "is not supported." % str(padding)
                    )
2075 2076 2077
                padding = padding[1:4]
                padding = [ele for a_list in padding for ele in a_list]
            padding = utils.convert_to_list(padding, 6, 'padding')
2078 2079
            if utils._is_symmetric_padding(padding, 3):
                padding = [padding[0], padding[2], padding[4]]
2080 2081 2082

        elif is_list_or_tuple(padding) and len(padding) == 6:
            padding = utils.convert_to_list(padding, 6, 'padding')
2083 2084
            if utils._is_symmetric_padding(padding, 3):
                padding = [padding[0], padding[2], padding[4]]
2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095
        else:
            padding = utils.convert_to_list(padding, 3, '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'."
2096 2097
                % str(pool_padding)
            )
2098 2099
        if pool_padding == "VALID":
            padding_algorithm = "VALID"
2100
            pool_padding = [0, 0, 0]
2101 2102 2103
            if ceil_mode != False:
                raise ValueError(
                    "When Attr(pool_padding) is \"VALID\", ceil_mode must be False. "
2104 2105
                    "Received ceil_mode: True."
                )
2106 2107
        elif pool_padding == "SAME":
            padding_algorithm = "SAME"
2108
            pool_padding = [0, 0, 0]
2109 2110 2111 2112 2113

    pool_padding = update_padding(pool_padding, data_format)

    op_type = "pool3d"
    helper = LayerHelper(op_type, **locals())
Y
Yu Yang 已提交
2114
    dtype = helper.input_dtype()
X
Xin Pan 已提交
2115
    pool_out = helper.create_variable_for_type_inference(dtype)
Y
Yu Yang 已提交
2116

2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134
    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,
        },
    )
Y
Yu Yang 已提交
2135 2136 2137 2138

    return pool_out


2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154
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,
):
2155
    r"""
2156 2157
    :api_attr: Static Graph

Q
qiaolongfei 已提交
2158 2159
    **Batch Normalization Layer**

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

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

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

Q
qiaolongfei 已提交
2167 2168 2169
    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 已提交
2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181

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

L
lvmengsi 已提交
2183
        moving\_mean = moving\_mean * momentum + mini-batch\_mean * (1. - momentum) \\\\
2184
        moving\_var = moving\_var * momentum + mini-batch\_var * (1. - momentum)
L
lvmengsi 已提交
2185

2186

L
lvmengsi 已提交
2187
    moving_mean is global mean and moving_var is global variance.
2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200

    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 已提交
2201
    Note:
2202
        if build_strategy.sync_batch_norm=True, the batch_norm in network will use
L
lvmengsi 已提交
2203
        sync_batch_norm automatically.
2204
        `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 已提交
2205

2206
    Args:
2207
        input(Tensor): The rank of input Tensor can be 2, 3, 4, 5. The data type
L
lvmengsi 已提交
2208
            is float16 or float32 or float64.
Q
qiaolongfei 已提交
2209
        act(string, Default None): Activation type, linear|relu|prelu|...
Q
qingqing01 已提交
2210 2211
        is_test (bool, Default False): A flag indicating whether it is in
            test phrase or not.
2212 2213
        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
2214
            shape [1] and data type as float32. The updated formula is:
Q
qingqing01 已提交
2215 2216 2217 2218 2219
            :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 已提交
2220 2221
        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
2222
	     will create ParamAttr as param_attr, the name of scale can be set in ParamAttr.
2223
	     If the Initializer of the param_attr is not set, the parameter is initialized
2224
	     with Xavier. Default: None.
C
chengduo 已提交
2225 2226
        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
2227 2228
	     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.
2229
	     Default: None.
2230
        data_layout (str, optional): Specify the data format of the input, and the data format of the output
K
Kaipeng Deng 已提交
2231 2232 2233
             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]`.
2234
        in_place(bool, Default False): Make the input and output of batch norm reuse memory.
2235 2236 2237 2238
        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
2239
            will save global mean with the string.
L
lvmengsi 已提交
2240
        moving_variance_name(str, Default None): The name of the moving_variance which store the global Variance.
2241
            If it is set to None, batch_norm will save global variance with a random name, otherwise, batch_norm
2242
            will save global variance with the string.
2243 2244
        do_model_average_for_mean_and_var(bool, Default True): Whether parameter mean and variance should do model
            average when model average is enabled.
2245 2246 2247 2248 2249
        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.
2250
    Returns:
2251
        A Tensor which is the result after applying batch normalization on the input,
2252
        has same shape and data type with input.
Q
qiaolongfei 已提交
2253 2254 2255 2256 2257

    Examples:

        .. code-block:: python

2258
            import paddle
2259

2260
            paddle.enable_static()
2261 2262 2263 2264 2265 2266 2267
            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 已提交
2268
    """
2269 2270 2271
    assert (
        bias_attr is not False
    ), "bias_attr should not be False in batch_norm."
Y
Yu Yang 已提交
2272 2273
    helper = LayerHelper('batch_norm', **locals())

2274 2275 2276
    check_variable_and_dtype(
        input, 'input', ['float16', 'float32', 'float64'], 'batch_norm'
    )
2277
    dtype = helper.input_dtype()
2278

W
Wu Yi 已提交
2279 2280 2281 2282
    # use fp32 for bn parameter
    if dtype == core.VarDesc.VarType.FP16:
        dtype = core.VarDesc.VarType.FP32

Y
Yu Yang 已提交
2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294
    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
2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314
    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,
    )
2315 2316
    mean.stop_gradient = True

2317 2318 2319 2320 2321 2322 2323 2324 2325 2326
    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,
    )
2327
    variance.stop_gradient = True
Y
Yu Yang 已提交
2328 2329 2330 2331

    # create output
    # mean and mean_out share the same memory
    mean_out = mean
2332
    # variance and variance_out share the same memory
Y
Yu Yang 已提交
2333
    variance_out = variance
2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345

    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:
2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361
            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,
            )
2362
        else:
2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376
            attrs_ = (
                'epsilon',
                epsilon,
                'is_test',
                is_test,
                'data_layout',
                data_layout,
                'use_mkldnn',
                False,
                'fuse_with_relu',
                False,
                'use_global_stats',
                use_global_stats,
            )
2377
        if inputs_has_MomemtumTensor:
2378
            batch_norm_out, _, _, _, _, _ = _legacy_C_ops.batch_norm(
2379 2380 2381 2382 2383 2384 2385 2386 2387 2388
                input,
                scale,
                bias,
                mean,
                variance,
                momentum,
                mean_out,
                variance_out,
                *attrs_,
            )
2389
        else:
2390
            batch_norm_out, _, _, _, _, _ = _legacy_C_ops.batch_norm(
2391 2392 2393 2394 2395 2396 2397 2398 2399 2400
                input,
                scale,
                bias,
                mean,
                variance,
                None,
                mean_out,
                variance_out,
                *attrs_,
            )
2401

2402 2403 2404
        return dygraph_utils._append_activation_in_dygraph(
            batch_norm_out, act=act, use_mkldnn=False
        )
2405

2406 2407 2408
    saved_mean = helper.create_variable_for_type_inference(
        dtype=dtype, stop_gradient=True
    )
X
Xin Pan 已提交
2409
    saved_variance = helper.create_variable_for_type_inference(
2410 2411
        dtype=dtype, stop_gradient=True
    )
2412
    reserve_space = None
2413
    if not is_test:
2414
        reserve_space = helper.create_variable_for_type_inference(
2415 2416
            dtype=helper.input_dtype(), stop_gradient=True
        )
2417

2418 2419 2420
    batch_norm_out = (
        input if in_place else helper.create_variable_for_type_inference(dtype)
    )
Y
Yu Yang 已提交
2421

2422 2423 2424 2425 2426
    inputs = {
        "X": input,
        "Scale": scale,
        "Bias": bias,
        "Mean": mean,
2427 2428
        "Variance": variance,
        "MeanOut": mean_out,
2429
        "VarianceOut": variance_out,
2430 2431 2432 2433 2434 2435 2436
    }
    attrs = {
        "epsilon": epsilon,
        "is_test": is_test,
        "data_layout": data_layout,
        "use_mkldnn": False,
        "fuse_with_relu": False,
2437
        "use_global_stats": use_global_stats,
2438 2439 2440 2441 2442
    }
    if isinstance(momentum, Variable):
        inputs['MomemtumTensor'] = momentum
    else:
        attrs['momentum'] = momentum
2443 2444 2445 2446 2447 2448

    outputs = {
        "Y": batch_norm_out,
        "MeanOut": mean_out,
        "VarianceOut": variance_out,
        "SavedMean": saved_mean,
2449
        "SavedVariance": saved_variance,
2450 2451 2452 2453
    }
    if reserve_space is not None:
        outputs["ReserveSpace"] = reserve_space

2454 2455 2456
    helper.append_op(
        type="batch_norm", inputs=inputs, outputs=outputs, attrs=attrs
    )
Y
Yu Yang 已提交
2457 2458 2459 2460

    return helper.append_activation(batch_norm_out)


Y
yuyang18 已提交
2461
@templatedoc()
2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472
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,
):
2473
    r"""
2474 2475
    :api_attr: Static Graph

2476 2477 2478 2479
    **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 已提交
2480 2481 2482

    The formula is as follows:

Y
yuyang18 已提交
2483
    ..  math::
G
guosheng 已提交
2484

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

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

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

2491 2492 2493 2494 2495
    - :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 已提交
2496

G
guosheng 已提交
2497
    Args:
2498
        input(Tensor): A multi-dimension ``Tensor`` , and the data type is float32 or float64.
2499 2500 2501 2502 2503
        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 已提交
2504
            dimensions from :attr:`begin_norm_axis` to :attr:`rank(input)`.
2505 2506 2507 2508
            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 已提交
2509 2510
            gain :math:`g`. If :attr:`scale` is False, :attr:`param_attr` is
            omitted. If :attr:`scale` is True and :attr:`param_attr` is None,
2511
            a default :code:`ParamAttr` would be added as scale. The
2512 2513
            :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 已提交
2514 2515
            bias :math:`b`. If :attr:`shift` is False, :attr:`bias_attr` is
            omitted. If :attr:`shift` is True and :attr:`param_attr` is None,
2516
            a default :code:`ParamAttr` would be added as bias. The
2517
            :attr:`bias_attr` is initialized as 0 if it is added. Default: None.
T
tianshuo78520a 已提交
2518
        act(str, optional): Activation to be applied to the output of layer normalization.
2519 2520
                  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 已提交
2521 2522

    Returns:
2523
        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 已提交
2524 2525 2526

    Examples:

2527 2528
        .. code-block:: python

2529 2530
            import paddle
            paddle.enable_static()
2531 2532 2533
            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 已提交
2534
    """
2535 2536 2537
    assert (
        _non_static_mode() is not True
    ), "please use LayerNorm instead of layer_norm in dygraph mode!"
G
guosheng 已提交
2538
    helper = LayerHelper('layer_norm', **locals())
2539 2540 2541
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'layer_norm'
    )
G
guosheng 已提交
2542 2543 2544 2545 2546 2547 2548
    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:
2549 2550 2551 2552 2553 2554 2555 2556 2557
        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 已提交
2558
        inputs['Scale'] = scale
2559 2560
    else:
        if param_attr:
T
tianshuo78520a 已提交
2561
            warnings.warn("param_attr is only available with scale is True.")
G
guosheng 已提交
2562
    if shift:
2563 2564 2565 2566 2567 2568
        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 已提交
2569
        inputs['Bias'] = bias
2570 2571
    else:
        if bias_attr:
T
tianshuo78520a 已提交
2572
            warnings.warn("bias_attr is only available with shift is True.")
G
guosheng 已提交
2573 2574

    # create output
2575 2576 2577 2578 2579 2580
    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 已提交
2581
    layer_norm_out = helper.create_variable_for_type_inference(dtype)
G
guosheng 已提交
2582

2583 2584 2585 2586 2587 2588 2589 2590 2591 2592
    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 已提交
2593 2594 2595 2596

    return helper.append_activation(layer_norm_out)


D
dengkaipeng 已提交
2597
@templatedoc()
2598
def spectral_norm(weight, dim=0, power_iters=1, eps=1e-12, name=None):
2599
    r"""
2600 2601
    :api_attr: Static Graph

D
dengkaipeng 已提交
2602 2603
    **Spectral Normalization Layer**

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

D
dengkaipeng 已提交
2609 2610 2611
    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 已提交
2612
    and W is the product result of remaining dimensions.
D
dengkaipeng 已提交
2613 2614

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

2619
    .. math::
D
dengkaipeng 已提交
2620 2621 2622 2623 2624 2625

        \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 已提交
2626
    Calculate :math:`\sigma(\mathbf{W})` and normalize weight values.
D
dengkaipeng 已提交
2627 2628 2629 2630

    .. math::

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

D
dengkaipeng 已提交
2632
        \mathbf{W} = \\frac{\mathbf{W}}{\sigma(\mathbf{W})}
2633

2634

D
dengkaipeng 已提交
2635 2636 2637
    Refer to `Spectral Normalization <https://arxiv.org/abs/1802.05957>`_ .

    Args:
C
Chen Long 已提交
2638
        weight(Tensor): ${weight_comment}
D
dengkaipeng 已提交
2639 2640 2641
        dim(int): ${dim_comment}
        power_iters(int): ${power_iters_comment}
        eps(float): ${eps_comment}
K
Kaipeng Deng 已提交
2642 2643 2644
        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 已提交
2645 2646

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

    Examples:
K
Kaipeng Deng 已提交
2651
       .. code-block:: python
D
dengkaipeng 已提交
2652

2653
            import paddle
K
Kaipeng Deng 已提交
2654

2655
            paddle.enable_static()
C
Chen Long 已提交
2656
            weight = paddle.static.data(name='weight', shape=[2, 8, 32, 32], dtype='float32')
2657
            x = paddle.static.nn.spectral_norm(weight=weight, dim=1, power_iters=2)
C
Chen Long 已提交
2658
            print(x.shape) # [2, 8, 32, 32]
D
dengkaipeng 已提交
2659 2660
    """
    helper = LayerHelper('spectral_norm', **locals())
2661 2662 2663
    check_variable_and_dtype(
        weight, 'weight', ['float32', 'float64'], 'spectral_norm'
    )
2664 2665 2666
    check_type(dim, 'dim', int, 'spectral_norm')
    check_type(power_iters, 'power_iters', int, 'spectral_norm')
    check_type(eps, 'eps', float, 'spectral_norm')
2667
    dtype = weight.dtype
D
dengkaipeng 已提交
2668 2669

    # create intput and parameters
2670
    input_shape = weight.shape
2671
    assert weight.numel() > 0, "Any dimension of input cannot be equal to 0."
2672 2673 2674 2675 2676
    assert dim < len(input_shape), (
        "The input `dim` should be less than the "
        "rank of `weight`, but received dim="
        "{}".format(dim)
    )
2677 2678 2679
    h = input_shape[dim]
    w = np.prod(input_shape) // h

2680 2681 2682 2683 2684 2685
    u = helper.create_parameter(
        attr=ParamAttr(),
        shape=[h],
        dtype=dtype,
        default_initializer=Normal(0.0, 1.0),
    )
2686
    u.stop_gradient = True
2687 2688 2689 2690 2691 2692
    v = helper.create_parameter(
        attr=ParamAttr(),
        shape=[w],
        dtype=dtype,
        default_initializer=Normal(0.0, 1.0),
    )
2693
    v.stop_gradient = True
D
dengkaipeng 已提交
2694

2695 2696 2697 2698 2699 2700 2701
    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 已提交
2702
    # create output
2703
    out = helper.create_variable(dtype=dtype)
D
Dun 已提交
2704

2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716
    helper.append_op(
        type="spectral_norm",
        inputs=inputs,
        outputs={
            "Out": out,
        },
        attrs={
            "dim": dim,
            "power_iters": power_iters,
            "eps": eps,
        },
    )
D
Dun 已提交
2717

2718
    return out
D
Dun 已提交
2719 2720


C
caoying03 已提交
2721
def reduce_sum(input, dim=None, keep_dim=False, name=None):
G
guosheng 已提交
2722
    """
2723

Y
yangyaming 已提交
2724
    Computes the sum of tensor elements over the given dimension.
G
guosheng 已提交
2725 2726

    Args:
2727 2728 2729
        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 已提交
2730 2731
            :attr:`None`, sum all elements of :attr:`input` and return a
            Tensor variable with a single element, otherwise must be in the
W
whs 已提交
2732 2733
            range :math:`[-rank(input), rank(input))`. If :math:`dim[i] < 0`,
            the dimension to reduce is :math:`rank + dim[i]`.
2734
        keep_dim (bool, optional): Whether to reserve the reduced dimension in the
Y
yangyaming 已提交
2735
            output Tensor. The result tensor will have one fewer dimension
2736 2737 2738 2739
            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 已提交
2740 2741

    Returns:
2742 2743
        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 已提交
2744

2745 2746
    Raises:
        TypeError, if out data type is different with the input data type.
2747

G
guosheng 已提交
2748 2749 2750
    Examples:
        .. code-block:: python

2751
            import paddle.fluid as fluid
2752 2753
            import paddle
            paddle.enable_static()
G
guosheng 已提交
2754 2755 2756
            # 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 已提交
2757
            # Each example is followed by the corresponding output tensor.
2758
            x = fluid.data(name='x', shape=[2, 4], dtype='float32')
G
guosheng 已提交
2759 2760 2761 2762
            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 已提交
2763

2764
            # y is a Tensor variable with shape [2, 2, 2] and elements as below:
W
whs 已提交
2765 2766
            #      [[[1, 2], [3, 4]],
            #      [[5, 6], [7, 8]]]
Q
qiaolongfei 已提交
2767
            # Each example is followed by the corresponding output tensor.
2768
            y = fluid.data(name='y', shape=[2, 2, 2], dtype='float32')
2769 2770
            fluid.layers.reduce_sum(y, dim=[1, 2]) # [10, 26]
            fluid.layers.reduce_sum(y, dim=[0, 1]) # [16, 20]
W
whs 已提交
2771

G
guosheng 已提交
2772
    """
2773 2774
    reduce_all, dim = _get_reduce_dim(dim, input)

2775
    if in_dygraph_mode():
2776
        return _C_ops.sum(input, dim, None, keep_dim)
2777
    elif _in_legacy_dygraph():
2778 2779 2780
        return _legacy_C_ops.reduce_sum(
            input, 'dim', dim, 'keep_dim', keep_dim, 'reduce_all', reduce_all
        )
2781
    attrs = {'dim': dim, 'keep_dim': keep_dim, 'reduce_all': reduce_all}
2782
    check_variable_and_dtype(
2783 2784 2785 2786 2787
        input,
        'input',
        ['float16', 'float32', 'float64', 'int32', 'int64'],
        'reduce_sum',
    )
2788
    helper = LayerHelper('reduce_sum', **locals())
X
Xin Pan 已提交
2789
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
2790 2791 2792 2793 2794 2795
    helper.append_op(
        type='reduce_sum',
        inputs={'X': input},
        outputs={'Out': out},
        attrs=attrs,
    )
G
guosheng 已提交
2796
    return out
G
guosheng 已提交
2797 2798


2799
@deprecated(since="2.0.0", update_to="paddle.mean")
C
caoying03 已提交
2800
def reduce_mean(input, dim=None, keep_dim=False, name=None):
G
guosheng 已提交
2801
    """
Y
Yibing Liu 已提交
2802
    Computes the mean of the input tensor's elements along the given dimension.
G
guosheng 已提交
2803 2804

    Args:
2805 2806 2807
        input (Variable): The input variable which is a Tensor, the data type is float32,
            float64, int32, int64.
        dim (list|int, optional): The dimension along which the mean is computed. If
Y
Yibing Liu 已提交
2808 2809
            `None`, compute the mean over all elements of :attr:`input`
            and return a variable with a single element, otherwise it
Y
yangyaming 已提交
2810
            must be in the range :math:`[-rank(input), rank(input))`. If
2811
            :math:`dim[i] < 0`, the dimension to reduce is
Y
Yibing Liu 已提交
2812
            :math:`rank(input) + dim[i]`.
2813
        keep_dim (bool, optional): Whether to reserve the reduced dimension in the
Y
yangyaming 已提交
2814
            output Tensor. The result tensor will have one fewer dimension
2815
            than the :attr:`input` unless :attr:`keep_dim` is true, default
2816 2817 2818
            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`
2819

G
guosheng 已提交
2820
    Returns:
2821 2822
        Variable: Tensor, results of average on the specified dim of input tensor,
        it's data type is the same as input's Tensor.
2823

2824 2825
    Raises:
        TypeError, if out data type is different with the input data type.
2826

G
guosheng 已提交
2827 2828 2829
    Examples:
        .. code-block:: python

2830
            import paddle
2831
            import paddle.fluid as fluid
2832 2833
            paddle.enable_static()

G
guosheng 已提交
2834 2835 2836
            # x is a Tensor variable with following elements:
            #    [[0.2, 0.3, 0.5, 0.9]
            #     [0.1, 0.2, 0.6, 0.7]]
T
tianshuo78520a 已提交
2837
            # Each example is followed by the corresponding output tensor.
2838
            x = fluid.data(name='x', shape=[2, 4], dtype='float32')
G
guosheng 已提交
2839 2840 2841
            fluid.layers.reduce_mean(x)  # [0.4375]
            fluid.layers.reduce_mean(x, dim=0)  # [0.15, 0.25, 0.55, 0.8]
            fluid.layers.reduce_mean(x, dim=-1)  # [0.475, 0.4]
2842
            fluid.layers.reduce_mean(x, dim=1, keep_dim=True)  # [[0.475], [0.4]]
W
whs 已提交
2843

2844
            # y is a Tensor variable with shape [2, 2, 2] and elements as below:
W
whs 已提交
2845 2846
            #      [[[1.0, 2.0], [3.0, 4.0]],
            #      [[5.0, 6.0], [7.0, 8.0]]]
T
tianshuo78520a 已提交
2847
            # Each example is followed by the corresponding output tensor.
2848
            y = fluid.data(name='y', shape=[2, 2, 2], dtype='float32')
2849 2850
            fluid.layers.reduce_mean(y, dim=[1, 2]) # [2.5, 6.5]
            fluid.layers.reduce_mean(y, dim=[0, 1]) # [4.0, 5.0]
G
guosheng 已提交
2851
    """
2852

2853
    return paddle.mean(x=input, axis=dim, keepdim=keep_dim, name=name)
2854 2855


Z
zhoukunsheng 已提交
2856 2857
def reduce_all(input, dim=None, keep_dim=False, name=None):
    """
2858

2859
    This OP computes the ``logical and`` of tensor elements over the given dimension, and output the result.
Z
zhoukunsheng 已提交
2860 2861

    Args:
2862
        input (Tensor): the input tensor, it's data type should be `bool`.
2863
        dim (list|int|optional): The dimension along which the logical and is computed.
Z
zhoukunsheng 已提交
2864 2865 2866
            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))`.
2867
            If :math:`dim[i] < 0`, the dimension to reduce is :math:`rank + dim[i]`. The default value is None.
Z
zhoukunsheng 已提交
2868 2869
        keep_dim (bool): Whether to reserve the reduced dimension in the
            output Tensor. The result tensor will have one fewer dimension
2870
            than the :attr:`input` unless :attr:`keep_dim` is true. The default value is False.
Z
zhoukunsheng 已提交
2871
        name(str|None): A name for this layer(optional). If set None, the layer
2872
                       will be named automatically. The default value is None.
Z
zhoukunsheng 已提交
2873

2874
    Returns:
2875
        Tensor, the output data type is bool. : The reduced tensor variable with ``logical and`` in given dims.
Z
zhoukunsheng 已提交
2876 2877 2878

    Examples:
        .. code-block:: python
2879

2880
            import paddle
2881
            import paddle.fluid as fluid
2882 2883 2884
            import paddle.fluid.layers as layers
            import numpy as np

Z
zhoukunsheng 已提交
2885 2886 2887
            # x is a bool Tensor variable with following elements:
            #    [[True, False]
            #     [True, True]]
2888 2889
            x = fluid.layers.assign(np.array([[1, 0], [1, 1]], dtype='int32'))
            x = fluid.layers.cast(x, 'bool')
2890

2891 2892 2893
            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]
2894 2895
            # keep_dim=False, x.shape=(2,2), out.shape=(2,)

2896
            out = fluid.layers.reduce_all(x, dim=1, keep_dim=True)  # [[False], [True]]
2897
            # keep_dim=True, x.shape=(2,2), out.shape=(2,1)
Z
zhoukunsheng 已提交
2898 2899

    """
2900 2901
    if dim is not None and not isinstance(dim, list):
        dim = [dim]
2902 2903

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

2906
    check_variable_and_dtype(input, 'input', ('bool'), 'reduce_all')
Z
zhoukunsheng 已提交
2907 2908
    helper = LayerHelper('reduce_all', **locals())
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
2909 2910 2911 2912 2913
    helper.append_op(
        type='reduce_all',
        inputs={'X': input},
        outputs={'Out': out},
        attrs={
2914
            'dim': dim if dim is not None and dim != [] else [0],
2915 2916
            'keep_dim': keep_dim,
            'reduce_all': True
2917
            if dim is None or dim == [] or len(dim) == len(input.shape)
2918 2919 2920
            else False,
        },
    )
Z
zhoukunsheng 已提交
2921 2922 2923 2924 2925
    return out


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

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

2940
    Returns:
2941
        Tensor, the output data type is bool. : The reduced tensor variable with ``logical or`` in given dims.
Z
zhoukunsheng 已提交
2942 2943 2944

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

2946
            import paddle
2947
            import paddle.fluid as fluid
2948 2949 2950
            import paddle.fluid.layers as layers
            import numpy as np

Z
zhoukunsheng 已提交
2951 2952 2953
            # x is a bool Tensor variable with following elements:
            #    [[True, False]
            #     [False, False]]
2954 2955
            x = fluid.layers.assign(np.array([[1, 0], [0, 0]], dtype='int32'))
            x = fluid.layers.cast(x, 'bool')
2956

2957 2958 2959
            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]
2960 2961
            # keep_dim=False, x.shape=(2,2), out.shape=(2,)

2962
            out = fluid.layers.reduce_any(x, dim=1,
Z
zhoukunsheng 已提交
2963
                                     keep_dim=True)  # [[True], [False]]
2964
            # keep_dim=True, x.shape=(2,2), out.shape=(2,1)
Z
zhoukunsheng 已提交
2965 2966

    """
2967
    check_variable_and_dtype(input, 'input', ('bool'), 'reduce_any')
Z
zhoukunsheng 已提交
2968 2969 2970 2971
    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]
2972 2973 2974 2975 2976
    helper.append_op(
        type='reduce_any',
        inputs={'X': input},
        outputs={'Out': out},
        attrs={
2977
            'dim': dim if dim is not None and dim != [] else [0],
2978 2979
            'keep_dim': keep_dim,
            'reduce_all': True
2980
            if dim is None or dim == [] or len(dim) == len(input.shape)
2981 2982 2983
            else False,
        },
    )
2984 2985 2986
    return out


C
caoying03 已提交
2987
def split(input, num_or_sections, dim=-1, name=None):
G
guosheng 已提交
2988
    """
2989
    Split the input tensor into multiple sub-Tensors.
G
guosheng 已提交
2990 2991

    Args:
2992
        input (Tensor): A N-D Tensor. The data type is bool, float16, float32, float64, int32 or int64.
2993
        num_or_sections (int|list|tuple): If ``num_or_sections`` is int, then the ``num_or_sections``
2994
            indicates the number of equal sized sub-Tensors that the ``input``
2995
            will be divided into. If ``num_or_sections`` is a list or tuple, the length of it
2996 2997 2998 2999 3000
            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.
3001
        name (str, optional): The default value is None.  Normally there is no need for user to set this property.
3002
            For more information, please refer to :ref:`api_guide_Name` .
G
guosheng 已提交
3003 3004

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

3007
    Example:
G
guosheng 已提交
3008 3009
        .. code-block:: python

3010 3011
            import paddle.fluid as fluid

3012
            # input is a Tensor which shape is [3, 9, 5]
3013
            input = fluid.data(
3014 3015
                 name="input", shape=[3, 9, 5], dtype="float32")

3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029
            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]
3030

3031 3032 3033 3034 3035 3036
            # 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]
3037

G
guosheng 已提交
3038
    """
J
Jiabin Yang 已提交
3039
    if _non_static_mode():
3040 3041 3042
        num = None
        attrs = ()

S
songyouwei 已提交
3043 3044
        if isinstance(dim, Variable):
            dim = dim.numpy()
3045
            dim = dim.item(0)
W
wangzhen38 已提交
3046
        assert len(input.shape) + dim >= 0, "(rank(x) + axis) must >= 0"
S
songyouwei 已提交
3047
        dim = (len(input.shape) + dim) if dim < 0 else dim
3048
        attrs += ('axis', dim)
3049 3050 3051

        if isinstance(num_or_sections, int):
            num = num_or_sections
3052
            attrs += ('num', num_or_sections)
L
Leo Chen 已提交
3053
        elif isinstance(num_or_sections, (list, tuple)):
3054
            num = len(num_or_sections)
L
Leo Chen 已提交
3055
            if utils._contain_var(num_or_sections):
3056 3057
                for index, item in enumerate(num_or_sections):
                    if isinstance(item, Variable):
3058 3059 3060
                        num_or_sections[index] = num_or_sections[index].numpy()[
                            0
                        ]
3061
                attrs += ('sections', list(num_or_sections))
L
Leo Chen 已提交
3062
            else:
3063
                attrs += ('sections', list(num_or_sections))
3064 3065
        else:
            raise TypeError(
3066
                "The type of 'num_or_sections' in split must be int, list or tuple in imperative mode, but "
3067 3068
                "received %s." % (type(num_or_sections))
            )
3069
        if in_dygraph_mode():
C
Charles-hit 已提交
3070 3071 3072 3073
            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)
3074 3075
        elif _in_legacy_dygraph():
            out = [_varbase_creator() for n in range(num)]
3076
            _legacy_C_ops.split(input, out, *attrs)
3077
            return out
L
Leo Chen 已提交
3078

3079
    check_variable_and_dtype(
3080 3081 3082 3083 3084
        input,
        'input',
        ['bool', 'float16', 'float32', 'float64', 'int32', 'int64'],
        'split',
    )
3085 3086 3087 3088
    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')
3089

G
guosheng 已提交
3090
    helper = LayerHelper('split', **locals())
3091

G
guosheng 已提交
3092
    input_shape = input.shape
3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103
    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:
3104
                assert isinstance(dim_size, int)
3105 3106 3107
                if dim_size == -1:
                    assert unk_dim_idx == -1, (
                        "Only one value of 'num_or_section' in split can "
3108 3109 3110
                        "be -1. But received num_or_section[%d] is also -1."
                        % idx
                    )
3111 3112
                    unk_dim_idx = idx
                temp_out = helper.create_variable_for_type_inference('int32')
3113 3114 3115
                fill_constant(
                    [1], 'int32', dim_size, force_cpu=True, out=temp_out
                )
3116 3117 3118 3119 3120 3121 3122
                tensor_list.append(temp_out)
        return tensor_list

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

G
guosheng 已提交
3127 3128
    if isinstance(num_or_sections, int):
        assert num_or_sections > 1, 'num_or_sections must be more than 1.'
3129
        if isinstance(dim, int) and input_shape[dim] > 0:
3130 3131 3132 3133 3134 3135
            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 已提交
3136 3137
        num = num_or_sections
    else:
3138
        if isinstance(dim, int) and input_shape[dim] > 0:
3139 3140 3141
            assert (
                len(num_or_sections) <= input_shape[dim]
            ), 'len(num_or_sections) must not be more than input.shape[dim].'
G
guosheng 已提交
3142
        num = len(num_or_sections)
3143
        attrs['sections'] = list(
3144 3145 3146 3147 3148
            map(
                lambda ele: -1 if isinstance(ele, Variable) else ele,
                num_or_sections,
            )
        )
L
Leo Chen 已提交
3149
        if utils._contain_var(num_or_sections):
3150
            inputs['SectionsTensorList'] = _get_SectionsTensorList(
3151 3152
                num_or_sections
            )
3153

G
guosheng 已提交
3154
    outs = [
X
Xin Pan 已提交
3155
        helper.create_variable_for_type_inference(dtype=helper.input_dtype())
G
guosheng 已提交
3156 3157
        for i in range(num)
    ]
3158 3159 3160
    helper.append_op(
        type='split', inputs=inputs, outputs={'Out': outs}, attrs=attrs
    )
G
guosheng 已提交
3161
    return outs
C
caoying03 已提交
3162 3163 3164


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

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

3170
    .. math::
3171 3172

        y = \\frac{x}{ \sqrt{\sum {x^2} + epsion }}
C
caoying03 已提交
3173 3174 3175 3176 3177

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

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

C
caoying03 已提交
3186
    Returns:
R
ruri 已提交
3187
        Variable: The output has the same shape and data type with `x`.
C
caoying03 已提交
3188 3189

    Examples:
3190

3191 3192
    .. code-block:: python
        :name: code-example1
3193

3194
        import paddle
3195

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

3200 3201 3202
        # [[ 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]]
3203

C
caoying03 已提交
3204
    """
F
fengjiayi 已提交
3205 3206
    if len(x.shape) == 1:
        axis = 0
J
Jiabin Yang 已提交
3207
    if _non_static_mode():
3208 3209 3210
        if in_dygraph_mode():
            out, _ = _C_ops.norm(x, 1 if axis is None else axis, epsilon, False)
        elif _in_legacy_dygraph():
3211 3212 3213
            _, out = _legacy_C_ops.norm(
                x, 'axis', 1 if axis is None else axis, 'epsilon', epsilon
            )
3214 3215 3216
        return out

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

3218
    helper = LayerHelper("l2_normalize", **locals())
X
Xin Pan 已提交
3219 3220
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
    norm = helper.create_variable_for_type_inference(dtype=x.dtype)
3221 3222 3223 3224 3225 3226 3227 3228 3229
    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 已提交
3230
    return out
3231 3232


S
ShenLiang 已提交
3233
@deprecated(since="2.0.0", update_to="paddle.matmul")
S
sneaxiy 已提交
3234
def matmul(x, y, transpose_x=False, transpose_y=False, alpha=1.0, name=None):
G
guosheng 已提交
3235
    """
Y
ying 已提交
3236 3237 3238 3239
    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 已提交
3240

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

3244 3245 3246 3247 3248
    - 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
3249
      :math:`[1, D]` in transposed form.
G
guosheng 已提交
3250

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

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

Y
ying 已提交
3259 3260
    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 已提交
3261
    removed after matrix multiplication.
G
guosheng 已提交
3262 3263 3264

    Args:
        x (Variable): The input variable which is a Tensor or LoDTensor.
3265 3266 3267
        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 已提交
3268
        alpha (float): The scale of output. Default 1.0.
3269
        name(str|None): A name for this layer(optional). If set None, the layer
3270
            will be named automatically.
G
guosheng 已提交
3271 3272

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

G
guosheng 已提交
3275 3276 3277
    Examples:
        .. code-block:: python

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

3282
            # x: [B, M, K], y: [B, K, N]
3283
            # fluid.layers.matmul(x, y)  # out: [B, M, N]
Y
ying 已提交
3284

3285
            # x: [B, M, K], y: [K, N]
3286
            # fluid.layers.matmul(x, y)  # out: [B, M, N]
Y
ying 已提交
3287

3288
            # x: [M, K], y: [K, N]
3289
            # fluid.layers.matmul(x, y)  # out: [M, N]
Y
ying 已提交
3290 3291

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

3294
            # x: [K], y: [K]
3295
            # fluid.layers.matmul(x, y)  # out: [1]
3296

Y
ying 已提交
3297
            # x: [M], y: [N]
3298 3299
            # fluid.layers.matmul(x, y, True, True)  # out: [M, N]

3300
            import paddle
3301
            import paddle.fluid as fluid
3302 3303
            paddle.enable_static()

3304 3305 3306
            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 已提交
3307
    """
J
Jiabin Yang 已提交
3308
    if _non_static_mode():
S
ShenLiang 已提交
3309
        out = _varbase_creator(dtype=x.dtype)
3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320
        _legacy_C_ops.matmul(
            x,
            y,
            out,
            'transpose_X',
            transpose_x,
            'transpose_Y',
            transpose_y,
            'alpha',
            float(alpha),
        )
S
ShenLiang 已提交
3321 3322 3323 3324 3325
        return out

    def __check_input(x, y):
        var_names = {'x': x, 'y': y}
        for name, val in var_names.items():
3326 3327 3328
            check_variable_and_dtype(
                val, name, ['float16', 'float32', 'float64'], 'matmul'
            )
S
ShenLiang 已提交
3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341
        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]:
3342 3343 3344 3345 3346 3347
            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 已提交
3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358

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

W
wanghuancoder 已提交
3362 3363 3364 3365 3366 3367
    attrs = {
        'transpose_X': transpose_x,
        'transpose_Y': transpose_y,
        'alpha': float(alpha),
    }

S
ShenLiang 已提交
3368 3369 3370 3371
    __check_input(x, y)

    helper = LayerHelper('matmul', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
3372 3373 3374 3375 3376 3377
    helper.append_op(
        type='matmul',
        inputs={'X': x, 'Y': y},
        outputs={'Out': out},
        attrs=attrs,
    )
S
ShenLiang 已提交
3378
    return out
3379 3380


3381
def topk(input, k, name=None):
Q
qingqing01 已提交
3382
    """
3383
    :alias_main: paddle.topk
3384 3385
        :alias: paddle.topk,paddle.tensor.topk,paddle.tensor.search.topk
        :old_api: paddle.fluid.layers.topk
3386

3387
    This OP is used to find values and indices of the k largest entries
Q
qingqing01 已提交
3388 3389
    for the last dimension.

3390 3391
    If the input is a 1-D Tensor, finds the k largest entries and outputs
    their values and indices.
Q
qingqing01 已提交
3392 3393 3394 3395

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

F
fengjiayi 已提交
3396 3397
    .. code-block:: text

3398 3399 3400 3401 3402
        Case 1:

          Input:
            input.shape = [3, 4]
            input.data = [[5, 4, 2, 3],
F
fengjiayi 已提交
3403 3404 3405 3406
                     [9, 7, 10, 25],
                     [6, 2, 10, 1]]
            k = 2

3407
          Output:
F
fengjiayi 已提交
3408
            The first output:
3409 3410
            values.shape = [3, 2]
            values.data = [[5, 4],
F
fengjiayi 已提交
3411 3412 3413 3414
                      [10, 25],
                      [6, 10]]

            The second output:
3415 3416
            indices.shape = [3, 2]
            indices.data = [[0, 1],
F
fengjiayi 已提交
3417 3418 3419
                       [2, 3],
                       [0, 2]]

Q
qingqing01 已提交
3420
    Args:
3421 3422 3423 3424
        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 已提交
3425 3426

    Returns:
3427 3428
        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 已提交
3429

F
fengjiayi 已提交
3430
    Raises:
3431
        ValueError: If :math:`k < 1` or :math:`k > last dimension of input`.
Q
qingqing01 已提交
3432 3433 3434 3435

    Examples:
        .. code-block:: python

3436
            import paddle.fluid as fluid
3437
            import paddle.fluid.layers as layers
3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450
            # 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 已提交
3451
    """
J
Jiabin Yang 已提交
3452
    if _non_static_mode():
3453
        _k = k.numpy().item(0) if isinstance(k, Variable) else k
3454
        out, indices = _legacy_C_ops.top_k(input, 'k', _k)
3455 3456 3457
        out.stop_gradient = True
        indices.stop_gradient = True
        return out, indices
3458

3459 3460
    inputs = {"X": [input]}
    attrs = {}
S
songyouwei 已提交
3461 3462 3463 3464 3465
    if isinstance(k, Variable):
        inputs['K'] = [k]
    else:
        attrs = {'k': k}

3466 3467 3468 3469
    helper = LayerHelper("top_k", **locals())
    values = helper.create_variable_for_type_inference(dtype=input.dtype)
    indices = helper.create_variable_for_type_inference(dtype="int64")

3470 3471 3472 3473 3474 3475
    helper.append_op(
        type="top_k",
        inputs=inputs,
        outputs={"Out": [values], "Indices": [indices]},
        attrs=attrs,
    )
Q
qingqing01 已提交
3476 3477 3478 3479 3480
    values.stop_gradient = True
    indices.stop_gradient = True
    return values, indices


3481 3482 3483
def ctc_greedy_decoder(
    input, blank, input_length=None, padding_value=0, name=None
):
3484
    r"""
S
SunGaofeng 已提交
3485
    This op is used to decode sequences by greedy policy by the following steps:
Y
yi.wu 已提交
3486

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

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

3496 3497 3498 3499 3500
    A simple example as below:

    .. code-block:: text

        Given:
S
SunGaofeng 已提交
3501
        (1) for lod mode:
3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512

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

3513
        input.lod = [[4, 4]]
M
minqiyang 已提交
3514

W
whs 已提交
3515
        Computation:
3516

W
whs 已提交
3517 3518 3519 3520 3521 3522
        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:
3523 3524 3525 3526 3527

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

3528
        output.lod = [[2, 1]]
3529

S
SunGaofeng 已提交
3530
        (2) for padding mode:
3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546

         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]
3547
        step2: Change the argmax result to use padding mode, then argmax result is
3548 3549 3550 3551 3552 3553 3554 3555 3556
                [[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 已提交
3557
    Parameters:
3558

3559 3560
        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 已提交
3561
                         where Lp is the sum of all input sequences' length and
3562 3563
                         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 已提交
3564
                         (not including the blank label). The data type can be float32 or float64.
Y
ying 已提交
3565
        blank(int): the blank label index of Connectionist Temporal
S
SunGaofeng 已提交
3566
                    Classification (CTC) loss, which is in the half-opened
Y
ying 已提交
3567
                    interval [0, num_classes + 1).
S
SunGaofeng 已提交
3568 3569
        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.
3570
        padding_value(int): padding value.
3571 3572 3573
        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`
3574 3575

    Returns:
S
SunGaofeng 已提交
3576 3577 3578 3579 3580
        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 [[]].

3581
        For padding mode, returns a tuple of (output, output_length), which was described as below:
S
SunGaofeng 已提交
3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592

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

3593 3594 3595 3596

    Examples:
        .. code-block:: python

3597
            # for lod mode
S
SunGaofeng 已提交
3598
            import paddle.fluid as fluid
S
SunGaofeng 已提交
3599
            x = fluid.data(name='x', shape=[None, 8], dtype='float32', lod_level=1)
3600
            cost = fluid.layers.ctc_greedy_decoder(input=x, blank=0)
3601 3602

            # for padding mode
S
SunGaofeng 已提交
3603 3604
            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')
3605 3606 3607
            out, out_len = fluid.layers.ctc_greedy_decoder(input=x_pad, blank=0,
                            input_length=x_pad_len)

W
wanghaoshuang 已提交
3608
    """
3609 3610 3611
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'ctc_greedy_decoder'
    )
3612

3613
    helper = LayerHelper("ctc_greedy_decoder", **locals())
Q
qingqing01 已提交
3614
    _, topk_indices = topk(input, k=1)
3615 3616

    # ctc align op
X
Xin Pan 已提交
3617
    ctc_out = helper.create_variable_for_type_inference(dtype="int64")
3618 3619

    if input_length is None:
3620 3621 3622 3623 3624 3625
        helper.append_op(
            type="ctc_align",
            inputs={"Input": [topk_indices]},
            outputs={"Output": [ctc_out]},
            attrs={"merge_repeated": True, "blank": blank},
        )
3626 3627 3628
        return ctc_out
    else:
        ctc_out_len = helper.create_variable_for_type_inference(dtype="int64")
3629
        ctc_input = paddle.squeeze(topk_indices, [2])
3630

3631 3632 3633 3634 3635 3636 3637 3638 3639 3640
        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,
            },
        )
3641
        return ctc_out, ctc_out_len
3642 3643


3644 3645 3646 3647 3648 3649 3650 3651 3652
def im2sequence(
    input,
    filter_size=1,
    stride=1,
    padding=0,
    input_image_size=None,
    out_stride=1,
    name=None,
):
3653
    r"""
3654 3655
    :api_attr: Static Graph

3656
    Extracts image patches from the input tensor to form a tensor of shape
L
Liufang Sang 已提交
3657 3658 3659
    {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
3660 3661
    output_height * output_width for an image, in which output_height and
    output_width are calculated by below equation:
3662 3663 3664

    .. math::

L
Liufang Sang 已提交
3665 3666 3667 3668
        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
3669

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

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

L
Liufang Sang 已提交
3675 3676 3677
        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.
3678

L
Liufang Sang 已提交
3679 3680
        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.
3681

L
Liufang Sang 已提交
3682 3683 3684 3685 3686
        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
3687
            padding_up = padding_down = padding_left = padding_right = padding.
L
Liufang Sang 已提交
3688
            Default is 0.
3689

L
Liufang Sang 已提交
3690 3691 3692 3693
        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 已提交
3694
            If out_stride is List,  it must contain two integers,
L
Liufang Sang 已提交
3695 3696 3697 3698 3699
            :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` .
3700 3701 3702

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

    Return Type: Variable
3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732

    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 已提交
3733 3734 3735
            filter = [2, 2]
            stride = [1, 1]
            padding = [0, 0]
3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747

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

3748
            output.dims = {8, 8}
3749

3750
            output.lod = [[4, 4]]
3751

T
Tink_Y 已提交
3752
    Examples:
3753 3754 3755

        .. code-block:: python

B
Bai Yifan 已提交
3756
            import paddle.fluid as fluid
3757 3758
            import paddle
            paddle.enable_static()
L
Liufang Sang 已提交
3759
            data = fluid.data(name='data', shape=[None, 3, 32, 32],
B
Bai Yifan 已提交
3760
                                     dtype='float32')
3761
            output = fluid.layers.im2sequence(
B
Bai Yifan 已提交
3762 3763
                input=data, stride=[1, 1], filter_size=[2, 2])

3764 3765

    """
3766 3767 3768
    assert (
        not _non_static_mode()
    ), "sequence layer is not supported in dygraph mode yet."
W
wanghaoshuang 已提交
3769

3770 3771
    check_variable_and_dtype(input, 'input', ['float32'], 'im2sequence')

W
wanghaoshuang 已提交
3772 3773 3774 3775 3776 3777 3778 3779 3780
    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])
3781
    inputs = {"X": input}
3782
    attrs = {"kernels": filter_size, "strides": stride, "paddings": padding}
3783 3784 3785 3786 3787
    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
3788
    helper = LayerHelper('im2sequence', **locals())
X
Xin Pan 已提交
3789
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
3790 3791 3792
    helper.append_op(
        type='im2sequence', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
3793
    return out
3794 3795


Y
yuyang18 已提交
3796
@templatedoc()
3797
def row_conv(input, future_context_size, param_attr=None, act=None):
Y
yuyang18 已提交
3798
    """
3799 3800
    :api_attr: Static Graph

Y
yuyang18 已提交
3801
    ${comment}
3802 3803

    Args:
Y
yuyang18 已提交
3804
        input (${x_type}): ${x_comment}.
Y
yangyaming 已提交
3805 3806
        future_context_size (int): Future context size. Please note, the shape
            of convolution kernel is [future_context_size + 1, D].
3807 3808 3809 3810 3811
        param_attr (ParamAttr): Attributes of parameters, including
            name, initializer etc.
        act (str): Non-linear activation to be applied to output variable.

    Returns:
Y
yuyang18 已提交
3812
        ${out_comment}.
3813 3814

    Examples:
B
Bai Yifan 已提交
3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826

      .. 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)
3827 3828
    """
    helper = LayerHelper('row_conv', **locals())
3829
    check_variable_and_dtype(input, 'input', ['float32'], 'row_conv')
3830
    dtype = helper.input_dtype()
3831
    filter_shape = [future_context_size + 1, input.shape[-1]]
3832 3833 3834
    filter_param = helper.create_parameter(
        attr=helper.param_attr, shape=filter_shape, dtype=dtype
    )
X
Xin Pan 已提交
3835
    out = helper.create_variable_for_type_inference(dtype)
3836 3837 3838 3839 3840
    helper.append_op(
        type='row_conv',
        inputs={'X': [input], 'Filter': [filter_param]},
        outputs={'Out': [out]},
    )
Y
yangyaming 已提交
3841
    return helper.append_activation(out)
3842 3843


Y
yuyang18 已提交
3844
@templatedoc()
3845
def multiplex(inputs, index, name=None):
3846
    """
Y
yuyang18 已提交
3847

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

3850
    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 已提交
3851

3852
    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 已提交
3853

3854
    For Example:
L
lujun 已提交
3855

3856
            .. code-block:: text
L
lujun 已提交
3857

3858
                Given:
L
lujun 已提交
3859

3860 3861 3862 3863
                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 已提交
3864

3865
                index = [[3],[0],[1],[2]]
L
lujun 已提交
3866

3867 3868 3869 3870
                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 已提交
3871 3872


3873
    Args:
3874 3875 3876 3877 3878
        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`.
3879
    Returns:
3880
        Tensor: Output of multiplex OP, with data type being float32, float64, int32, int64.
X
xuezhong 已提交
3881 3882

    Examples:
3883

X
xuezhong 已提交
3884 3885
        .. code-block:: python

3886
            import paddle
3887 3888 3889
            import numpy as np
            img1 = np.array([[1, 2], [3, 4]]).astype(np.float32)
            img2 = np.array([[5, 6], [7, 8]]).astype(np.float32)
3890 3891 3892
            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)
3893
            print(res) # [array([[5., 6.], [3., 4.]], dtype=float32)]
X
xuezhong 已提交
3894

3895
    """
3896 3897

    if _in_legacy_dygraph():
3898
        return _legacy_C_ops.multiplex(index, inputs)
3899
    if in_dygraph_mode():
3900
        return _C_ops.multiplex(inputs, index)
3901 3902
    helper = LayerHelper('multiplex', **locals())

3903 3904 3905
    check_type(inputs, 'inputs', (list), 'multiplex')
    if len(inputs) < 2:
        raise ValueError(
3906 3907
            "inputs should be a list object with at least 2 elements."
        )
3908
    for id, x in enumerate(inputs):
3909 3910 3911 3912 3913 3914
        check_variable_and_dtype(
            x,
            'input[' + str(id) + ']',
            ['float32', 'float64', 'int32', 'int64'],
            'multiplex',
        )
3915
    check_variable_and_dtype(index, "index", ['int32', 'int64'], 'multiplex')
3916 3917

    out = helper.create_variable_for_type_inference(inputs[0].dtype)
3918 3919 3920 3921 3922
    helper.append_op(
        type='multiplex',
        inputs={'X': inputs, 'Ids': index},
        outputs={'Out': [out]},
    )
3923
    return out
X
xuezhong 已提交
3924 3925


3926 3927
def smooth_l1(x, y, inside_weight=None, outside_weight=None, sigma=None):
    """
3928

Y
Yibing Liu 已提交
3929 3930
    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 已提交
3931
    For each instance, it computes the smooth L1 loss element by element first
T
tianshuo78520a 已提交
3932
    and then sums all the losses. So the shape of output Variable is
3933
    [batch_size, 1].
3934

3935 3936
    Args:
        x (Variable): A tensor with rank at least 2. The input value of smooth
Q
qingqing01 已提交
3937
            L1 loss op with shape [batch_size, dim1, ..., dimN].
3938
            A LoDTensor or Tensor with type float32.
3939
        y (Variable): A tensor with rank at least 2. The target value of smooth
Y
Yibing Liu 已提交
3940
            L1 loss op with same shape as :attr:`x`.
3941
            A LoDTensor or Tensor with type float32.
3942
        inside_weight (Variable|None):  A tensor with rank at least 2. This
3943 3944
            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 已提交
3945
            by this tensor element by element.
3946
            A Tensor with type float32.
3947
        outside_weight (Variable|None): A tensor with rank at least 2. This
3948 3949
            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 已提交
3950
            element by element.
3951
            A Tensor with type float32.
3952
        sigma (float|None): Hyper parameter of smooth L1 loss layer. A float
3953 3954
           scalar with default value 1.0.

3955
    Returns:
3956
        Variable: The output smooth L1 loss with shape [batch_size, 1].  A Tensor with type float32.
3957 3958 3959 3960

    Examples:
        .. code-block:: python

3961
            import paddle.fluid as fluid
3962
            import numpy as np
3963 3964
            import paddle
            paddle.enable_static()
3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975
            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)
3976

3977 3978 3979 3980
            #[array([[0.08220536],
            #       [0.36652038],
            #      [0.20541131]], dtype=float32)]

3981
    """
3982 3983
    check_variable_and_dtype(x, 'X', ['float32', 'float64'], 'smooth_l1_loss')
    check_variable_and_dtype(y, 'Y', ['float32', 'float64'], 'smooth_l1_loss')
3984

3985
    helper = LayerHelper('smooth_l1_loss', **locals())
3986

X
Xin Pan 已提交
3987 3988
    diff = helper.create_variable_for_type_inference(dtype=x.dtype)
    loss = helper.create_variable_for_type_inference(dtype=x.dtype)
3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999
    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},
    )
4000
    return loss
4001 4002


4003
@deprecated(since='2.0.0', update_to='paddle.nn.functional.one_hot')
4004
def one_hot(input, depth, allow_out_of_range=False):
4005
    """
4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043

    **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.],
4044
                        [0., 1., 0., 0.],
4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056
                        [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
4057
            The second dimension in X is 5, which is greater than depth.
4058 4059
            Allow_out_of_range =False means that does not allow the word id to exceed depth,
            so it throws an exception.
4060 4061

    Args:
4062 4063 4064
        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.
4065
        depth(scalar): An integer defining the :attr:`depth` of the one hot dimension. If input
4066
            is word id, depth is generally the dictionary size.
4067
        allow_out_of_range(bool): A bool value indicating whether the input
4068 4069 4070 4071
            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.
4072 4073

    Returns:
4074
        Variable: The one-hot representations of input. A Tensor or LoDTensor with type float32.
4075 4076

    Examples:
C
caoying03 已提交
4077
        .. code-block:: python
4078

4079
            import paddle
4080
            import paddle.fluid as fluid
4081 4082
            paddle.enable_static()

4083 4084 4085
            # 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)
4086
    """
J
Jiabin Yang 已提交
4087
    if _non_static_mode():
S
songyouwei 已提交
4088 4089 4090
        if isinstance(depth, Variable):
            depth = depth.numpy()
            assert depth.shape == (
4091 4092
                1,
            ), "depth of type Variable should have shape [1]"
4093
            depth = depth.item(0)
4094 4095 4096
        out = _legacy_C_ops.one_hot(
            input, 'depth', depth, 'allow_out_of_range', allow_out_of_range
        )
4097 4098
        out.stop_gradient = True
        return out
4099

4100
    helper = LayerHelper("one_hot", **locals())
4101
    check_variable_and_dtype(input, 'input', ['int32', 'int64'], 'one_hot')
4102
    check_type(depth, 'depth', (int, Variable), 'one_hot')
X
Xin Pan 已提交
4103
    one_hot_out = helper.create_variable_for_type_inference(dtype='float32')
4104

4105 4106
    if not isinstance(depth, Variable):
        # user attribute
4107
        inputs = {'X': input}
Y
Yi Liu 已提交
4108
        attrs = {'depth': depth, 'allow_out_of_range': allow_out_of_range}
4109
    else:
4110 4111 4112
        depth.stop_gradient = True
        inputs = {'X': input, 'depth_tensor': depth}
        attrs = {'allow_out_of_range': allow_out_of_range}
4113 4114 4115
    helper.append_op(
        type="one_hot", inputs=inputs, attrs=attrs, outputs={'Out': one_hot_out}
    )
4116
    one_hot_out.stop_gradient = True
4117
    return one_hot_out
Y
Yu Yang 已提交
4118 4119


Y
Yu Yang 已提交
4120
def autoincreased_step_counter(counter_name=None, begin=1, step=1):
Y
Yu Yang 已提交
4121
    """
4122 4123
    :api_attr: Static Graph

4124 4125
    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 已提交
4126
    and the step size is 1.
Y
Yu Yang 已提交
4127 4128

    Args:
Y
Yibing Liu 已提交
4129 4130 4131
        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 已提交
4132

4133
    Returns:
Y
Yibing Liu 已提交
4134
        Variable: The auto-increased Variable with data type int64.
Y
yi.wu 已提交
4135 4136 4137 4138

    Examples:
        .. code-block:: python

4139
           import paddle.fluid as fluid
4140 4141
           import paddle
           paddle.enable_static()
Y
yi.wu 已提交
4142
           global_step = fluid.layers.autoincreased_step_counter(
Y
Yibing Liu 已提交
4143
               counter_name='@LR_DECAY_COUNTER@', begin=0, step=1)
Y
Yu Yang 已提交
4144 4145
    """
    helper = LayerHelper('global_step_counter')
Y
Yu Yang 已提交
4146 4147
    if counter_name is None:
        counter_name = '@STEP_COUNTER@'
Y
Yu Yang 已提交
4148
    counter, is_new_var = helper.create_or_get_global_variable(
H
hong 已提交
4149 4150 4151 4152
        name=counter_name,
        dtype='int64',
        shape=[1],
        persistable=True,
4153 4154
        belong_to_optimizer=True,
    )
Y
Yu Yang 已提交
4155
    if is_new_var:
4156 4157 4158
        helper.set_variable_initializer(
            counter, initializer=Constant(value=begin - 1, force_cpu=True)
        )
W
Wu Yi 已提交
4159
        helper.main_program.global_block()._prepend_op(
Y
Yu Yang 已提交
4160 4161
            type='increment',
            inputs={'X': [counter]},
Y
Yu Yang 已提交
4162
            outputs={'Out': [counter]},
4163 4164
            attrs={'step': float(step)},
        )
Y
Yu Yang 已提交
4165 4166 4167
        counter.stop_gradient = True

    return counter
Y
yangyaming 已提交
4168 4169


4170
def unsqueeze(input, axes, name=None):
Y
Yibing Liu 已提交
4171
    """
4172
    Insert single-dimensional entries to the shape of a Tensor. Takes one
M
minqiyang 已提交
4173 4174
    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 已提交
4175

M
minqiyang 已提交
4176
    For example:
H
haowang101779990 已提交
4177 4178 4179

    .. code-block:: text

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

Y
Yibing Liu 已提交
4183
    Args:
4184
        input (Variable): The input Tensor to be unsqueezed. Supported data type: float32, float64, bool, int8, int32, int64.
4185
        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 .
4186
        name (str|None): Name for this layer.
Y
Yibing Liu 已提交
4187 4188

    Returns:
4189
        Variable: Unsqueezed Tensor, with the same data type as input.
Y
Yibing Liu 已提交
4190 4191 4192 4193

    Examples:
        .. code-block:: python

4194 4195 4196
            import paddle.fluid as fluid
            x = fluid.layers.data(name='x', shape=[5, 10])
            y = fluid.layers.unsqueeze(input=x, axes=[1])
4197

Y
Yibing Liu 已提交
4198
    """
J
Jiabin Yang 已提交
4199
    if _non_static_mode():
L
Leo Chen 已提交
4200 4201 4202
        if isinstance(axes, int):
            axes = [axes]
        elif isinstance(axes, Variable):
4203
            axes = axes.numpy().tolist()
L
Leo Chen 已提交
4204 4205 4206 4207 4208
        elif isinstance(axes, (list, tuple)):
            axes = [
                item.numpy().item(0) if isinstance(item, Variable) else item
                for item in axes
            ]
4209
        if _in_legacy_dygraph():
4210
            out, _ = _legacy_C_ops.unsqueeze2(input, 'axes', axes)
4211
            return out
4212
        return _C_ops.unsqueeze(input, axes)
4213 4214

    check_type(axes, 'axis/axes', (int, list, tuple, Variable), 'unsqueeze')
4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231
    check_variable_and_dtype(
        input,
        'input',
        [
            'float16',
            'float32',
            'float64',
            'bool',
            'int8',
            'int16',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        'unsqueeze',
    )
4232 4233 4234 4235 4236 4237 4238 4239 4240 4241
    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 已提交
4242
        if utils._contain_var(axes):
4243
            inputs["AxesTensorList"] = utils._convert_to_tensor_list(axes)
4244 4245 4246
        else:
            attrs["axes"] = axes

X
Xin Pan 已提交
4247 4248
    out = helper.create_variable_for_type_inference(dtype=input.dtype)
    x_shape = helper.create_variable_for_type_inference(dtype=input.dtype)
4249 4250 4251 4252 4253 4254
    helper.append_op(
        type="unsqueeze2",
        inputs=inputs,
        attrs=attrs,
        outputs={"Out": out, "XShape": x_shape},
    )
Y
Yibing Liu 已提交
4255

4256 4257
    return out

4258

Y
yangyaming 已提交
4259
def lod_reset(x, y=None, target_lod=None):
Y
yangyaming 已提交
4260
    """
Y
Yibing Liu 已提交
4261
    Set LoD of :attr:`x` to a new one specified by :attr:`y` or
4262 4263 4264 4265
    :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
4266
    :attr:`y.data` or :attr:`target_lod`, only one level LoD is supported.
Y
yangyaming 已提交
4267 4268 4269 4270 4271 4272

    .. code-block:: text

        * Example 1:

            Given a 1-level LoDTensor x:
4273
                x.lod =  [[ 2,           3,                   1 ]]
Y
yangyaming 已提交
4274 4275 4276
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

4277
            target_lod: [4, 2]
Y
yangyaming 已提交
4278 4279

            then we get a 1-level LoDTensor:
4280
                out.lod =  [[4,                          2]]
Y
yangyaming 已提交
4281 4282 4283 4284 4285 4286
                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:
4287
                x.lod =  [[2,            3,                   1]]
Y
yangyaming 已提交
4288 4289 4290 4291
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

            y is a Tensor:
4292
                y.data = [[2, 4]]
Y
yangyaming 已提交
4293 4294 4295
                y.dims = [1, 3]

            then we get a 1-level LoDTensor:
4296
                out.lod =  [[2,            4]]
Y
yangyaming 已提交
4297 4298 4299 4300 4301 4302
                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:
4303
                x.lod =  [[2,            3,                   1]]
Y
yangyaming 已提交
4304 4305 4306 4307
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

            y is a 2-level LoDTensor:
4308
                y.lod =  [[2, 2], [2, 2, 1, 1]]
Y
yangyaming 已提交
4309 4310 4311 4312
                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:
4313
                out.lod =  [[2, 2], [2, 2, 1, 1]]
Y
yangyaming 已提交
4314 4315 4316 4317
                out.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                out.dims = [6, 1]

    Args:
4318
        x (Variable): Input variable which could be a Tensor or LoDTensor.
4319
                      The data type should be int32, int64, float32 or float64.
4320 4321
        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.
4322 4323
                                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 已提交
4324
                                      as target LoD when :attr:`y` not provided.
Y
yangyaming 已提交
4325 4326

    Returns:
Y
Yibing Liu 已提交
4327
        Variable: Output variable with LoD specified by this layer.
Y
yangyaming 已提交
4328 4329

    Raises:
Y
Yibing Liu 已提交
4330
        ValueError: If :attr:`y` and :attr:`target_lod` are both None.
Y
yangyaming 已提交
4331 4332 4333 4334

    Examples:
        .. code-block:: python

4335
            import paddle.fluid as fluid
4336 4337 4338
            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 已提交
4339
    """
4340 4341 4342
    check_variable_and_dtype(
        x, 'x', ['float32', 'float64', 'int32', 'int64'], 'lod_reset'
    )
Y
yangyaming 已提交
4343
    helper = LayerHelper("lod_reset", **locals())
X
Xin Pan 已提交
4344
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
Y
yangyaming 已提交
4345
    if y is not None:
4346
        check_type(y, 'y', (Variable), 'lod_reset')
4347 4348 4349 4350
        # TODO: check y.lod_level = 0 dtype
        helper.append_op(
            type="lod_reset", inputs={'X': x, 'Y': y}, outputs={'Out': out}
        )
Y
yangyaming 已提交
4351
    elif target_lod is not None:
4352 4353 4354 4355 4356 4357
        helper.append_op(
            type="lod_reset",
            inputs={'X': x},
            attrs={'target_lod': target_lod},
            outputs={'Out': out},
        )
Y
yangyaming 已提交
4358
    else:
4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383
        raise ValueError("y and target_lod should not be both none.")
    return out


def lod_append(x, level):
    """
    Append level to LoD of :attr:`x`.

    .. code-block:: text

        * Example 1:

            given a 1-level LoDTensor x:
                x.lod =  [[ 2,           3,                   1 ]]
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

            level: [1, 1, 1, 1, 1, 1, 1]

            then we get a 2-level LoDTensor:
                x.lod =  [[ 2, 3, 1 ], [1, 1, 1, 1, 1, 1]]
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

    Args:
4384
        x (Variable): Input variable which could be a tensor or LoDTensor.
4385
                      The data type should be int32, int64, float32 or float64.
4386
        level (list|tuple|Variable, optional): The LoD level to be appended into LoD of x.
4387 4388
                                               If level is variable and its lod level>0, the data type can be any type.
                                               If level is variable and its lod level=0, the data type should be int32.
4389 4390 4391 4392 4393
    Returns:
        Variable: Output variable with new LoD level.

    Raises:
        ValueError: If :attr:`y` is None or and :attr:`level` is not Iterator.
Y
yangyaming 已提交
4394

4395 4396 4397 4398 4399 4400 4401 4402 4403
    Examples:
        .. code-block:: python

            import paddle.fluid as fluid
            x = fluid.layers.data(name='x', shape=[6, 10], lod_level=1)
            out = fluid.layers.lod_append(x, [1,1,1,1,1,1])
    """
    if x is None:
        raise ValueError("Input(x) can't be None.")
4404 4405 4406
    if (not isinstance(level, Iterable)) and (not isinstance(level, Variable)):
        raise ValueError("Input(level) must be list, tuple or Variable.")

4407 4408 4409
    check_variable_and_dtype(
        x, 'x', ['float32', 'float64', 'int32', 'int64'], 'lod_append'
    )
4410

4411 4412
    helper = LayerHelper("lod_append", **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
4413 4414 4415 4416 4417 4418

    inputs = {'X': x}
    attrs = {'append': True}

    if isinstance(level, Variable):
        inputs['Y'] = level
4419
        # TODO: check y.lod_level = 0 dtype
4420 4421
    else:
        attrs['target_lod'] = level
4422 4423 4424
    helper.append_op(
        type="lod_reset", inputs=inputs, attrs=attrs, outputs={'Out': out}
    )
Y
yangyaming 已提交
4425
    return out
D
dragonwarrior 已提交
4426 4427


4428
def pad(x, paddings, pad_value=0.0, name=None):
4429
    r"""
4430
    :alias_main: paddle.nn.functional.pad
4431 4432
        :alias: paddle.nn.functional.pad,paddle.nn.functional.common.pad
        :old_api: paddle.fluid.layers.pad
4433

S
SunGaofeng 已提交
4434 4435
    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 已提交
4436

S
SunGaofeng 已提交
4437 4438 4439 4440
    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 已提交
4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458

    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 已提交
4459
        x (Variable): Tensor, data type is float32.
G
guosheng 已提交
4460
        paddings (list): A list of integers. Its elements specify the padded
S
SunGaofeng 已提交
4461
                         width before and after each dimension in turn.
4462
                         The length of :attr:`paddings` must be equal to
G
guosheng 已提交
4463 4464
                         :math:`rank(x) \\times 2`.
        pad_value (float): The constant value used to pad.
4465 4466
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
4467
                             For more information, please refer to :ref:`api_guide_Name`
G
guosheng 已提交
4468 4469

    Returns:
S
SunGaofeng 已提交
4470 4471 4472 4473
        The padded tensor, with the same data type and rank as :attr:`x`

    Return Type:
        Variable
G
guosheng 已提交
4474 4475 4476

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

4478
            # x is a rank 2 tensor variable
S
SunGaofeng 已提交
4479
            import paddle.fluid as fluid
4480 4481
            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 已提交
4482
    """
4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496
    check_variable_and_dtype(
        x,
        'x',
        [
            'float16',
            'float32',
            'float64',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        "pad",
    )
4497

4498 4499 4500 4501
    check_type(pad_value, 'pad_value', (float, int, Variable), 'pad')
    if isinstance(pad_value, int):
        pad_value = float(pad_value)

4502 4503
    helper = LayerHelper('pad', **locals())
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
4504
    out = helper.create_variable_for_type_inference(dtype)
4505 4506 4507 4508 4509 4510
    helper.append_op(
        type='pad',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'paddings': paddings, 'pad_value': pad_value},
    )
G
guosheng 已提交
4511
    return out
4512 4513


4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524
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',
):
4525
    """
4526

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

4529 4530
    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)
4531 4532
    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 已提交
4533
    and the resizing only applies on the three dimensions(depth, height and width).
4534

4535
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in the
4536 4537
    future and only use :attr:`out_shape` instead.

4538
    Supporting resample methods:
4539
        'LINEAR' : Linear interpolation
Q
update  
qiaolongfei 已提交
4540

4541
        'BILINEAR' : Bilinear interpolation
T
Tink_Y 已提交
4542

K
Kaipeng Deng 已提交
4543 4544
        'TRILINEAR' : Trilinear interpolation

4545
        'NEAREST' : Nearest neighbor interpolation
4546

4547
        'BICUBIC' : Bicubic interpolation
4548 4549

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

4552
    Nearest neighbor interpolation is to perform nearest neighbor interpolation
4553
    in both the 3rd dimension(in height direction) and the 4th dimension(in width
4554
    direction) on input tensor.
4555 4556 4557 4558 4559

    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
4560 4561
    again in the other direction.

4562 4563 4564
    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 已提交
4565
    The linear interpolation is performed on three directions.
4566

4567 4568 4569 4570
    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 已提交
4571

4572
    Align_corners and align_mode are optional parameters,the calculation method
4573 4574 4575 4576
    of interpolation can be selected by them.

    Example:

T
Tink_Y 已提交
4577
    .. code-block:: text
4578

T
Tink_Y 已提交
4579
        For scale:
4580

T
Tink_Y 已提交
4581
            if align_corners = True && out_size > 1 :
4582

T
Tink_Y 已提交
4583
              scale_factor = (in_size-1.0)/(out_size-1.0)
4584

T
Tink_Y 已提交
4585
            else:
4586

T
Tink_Y 已提交
4587
              scale_factor = float(in_size/out_size)
4588 4589


T
Tink_Y 已提交
4590
        Nearest neighbor interpolation:
4591

T
Tink_Y 已提交
4592 4593
          if:
              align_corners = False
4594

T
Tink_Y 已提交
4595 4596
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4597

T
Tink_Y 已提交
4598 4599
              H_out = floor (H_{in} * scale_{factor})
              W_out = floor (W_{in} * scale_{factor})
4600

T
Tink_Y 已提交
4601 4602
          else:
              align_corners = True
4603

T
Tink_Y 已提交
4604 4605
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4606

T
Tink_Y 已提交
4607 4608
              H_out = round(H_{in} * scale_{factor})
              W_out = round(W_{in} * scale_{factor})
4609

4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626
        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 已提交
4627 4628 4629 4630
        Bilinear interpolation:

          if:
              align_corners = False , align_mode = 0
4631

T
Tink_Y 已提交
4632 4633
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4634

T
Tink_Y 已提交
4635 4636
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5
4637

T
Tink_Y 已提交
4638
          else:
4639

T
Tink_Y 已提交
4640 4641
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4642

T
Tink_Y 已提交
4643 4644
              H_out = H_{in} * scale_{factor}
              W_out = W_{in} * scale_{factor}
4645

K
Kaipeng Deng 已提交
4646 4647 4648 4649
        Trilinear interpolation:

          if:
              align_corners = False , align_mode = 0
4650

K
Kaipeng Deng 已提交
4651 4652
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:
4653

K
Kaipeng Deng 已提交
4654 4655 4656 4657 4658 4659
              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:
4660

K
Kaipeng Deng 已提交
4661 4662 4663 4664
              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}
4665

4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677
        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 已提交
4678 4679
              H_out = H_{in} * scale_{factor}
              W_out = W_{in} * scale_{factor}
4680

4681

4682 4683
    For details of linear interpolation, please refer to Wikipedia:
    https://en.wikipedia.org/wiki/Linear_interpolation.
4684

4685
    For details of nearest neighbor interpolation, please refer to Wikipedia:
4686
    https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation.
4687

4688
    For details of bilinear interpolation, please refer to Wikipedia:
4689
    https://en.wikipedia.org/wiki/Bilinear_interpolation.
4690

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

4694 4695
    For details of bicubic interpolation, please refer to Wikipedia:
    https://en.wikipedia.org/wiki/Bicubic_interpolation
4696

R
ruri 已提交
4697
    Parameters:
4698
        input (Variable): 3-D, 4-D or 5-D Tensor, its data type is float32, float64, or uint8,
4699
                          its data format is specified by :attr:`data_format`.
4700
        out_shape (list|tuple|Variable|None): Output shape of image resize
4701 4702
             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.
4703
             Default: None. If a list, each element can be an integer or a Tensor Variable of shape: [1].
4704
             If a Tensor Variable, its dimensions size should be a 1.
4705 4706 4707
        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 已提交
4708
             Default: None.
4709 4710
        name(str|None): A name for this layer(optional). If set None, the layer
                        will be named automatically.
4711
        resample(str): The resample method. It supports 'LINEAR', 'BICUBIC', 'BILINEAR', 'TRILINEAR'
K
Kaipeng Deng 已提交
4712
                       and 'NEAREST' currently. Default: 'BILINEAR'
4713 4714 4715
        actual_shape(Variable): An optional input to specify output shape
                                dynamically. If provided, image resize
                                according to this given shape rather than
4716
                                :attr:`out_shape` and :attr:`scale` specifying
4717 4718
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
4719 4720 4721 4722 4723
                                :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 已提交
4724
                                errors would be occurred in graph constructing stage.
4725
                                Default: None
4726 4727
        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
4728 4729
                               corner pixels.
                               Default: True
4730 4731
        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 ,
4732
                            can be \'1\' for src_idx = scale*dst_index.
4733
        data_format (str, optional): Specify the data format of the input, and the data format of the output
4734
            will be consistent with that of the input. An optional string from:`NCW`, `NWC`, `"NCHW"`, `"NHWC"`, `"NCDHW"`,
4735
            `"NDHWC"`. The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
4736
            `[batch_size, input_channels, input_height, input_width]`. When it is `"NCHW"`, the data is stored
4737
            in the order of: `[batch_size, input_channels, input_depth, input_height, input_width]`.
4738 4739

    Returns:
4740
        A 3-D Tensor of the shape (num_batches, channels, out_w) or (num_batches, out_w, channels),
4741 4742
        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 已提交
4743

4744 4745 4746
    Raises:
        TypeError: out_shape should be a list or tuple or Variable.
        TypeError: actual_shape should either be Variable or None.
4747 4748
        ValueError: The 'resample' of image_resize can only be 'LINEAR', 'BILINEAR',
                    'TRILINEAR', 'BICUBIC' or 'NEAREST' currently.
4749
        ValueError: 'LINEAR' only support 3-D tensor.
4750
        ValueError: 'BICUBIC', 'BILINEAR' and 'NEAREST' only support 4-D tensor.
K
Kaipeng Deng 已提交
4751
        ValueError: 'TRILINEAR' only support 5-D tensor.
4752
        ValueError: One of out_shape and scale must not be None.
4753
        ValueError: out_shape length should be 1 for input 3-D tensor.
K
Kaipeng Deng 已提交
4754 4755
        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 已提交
4756
        ValueError: scale should be greater than zero.
T
tianshuo78520a 已提交
4757
        TypeError: align_corners should be a bool value
4758
        ValueError: align_mode can only be '0' or '1'
4759
        ValueError: data_format can only be 'NCW', 'NWC', 'NCHW', 'NHWC', 'NCDHW' or 'NDHWC'.
4760

4761 4762
    Examples:
        .. code-block:: python
4763

4764 4765 4766 4767 4768 4769
            #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 已提交
4770

4771 4772
            #1
            output = fluid.layers.image_resize(input=input,out_shape=[12,12])
R
ruri 已提交
4773

4774 4775 4776 4777 4778
            #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 已提交
4779

4780 4781 4782 4783 4784
            #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 已提交
4785

4786 4787 4788 4789 4790
            #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 已提交
4791

4792 4793 4794
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
4795

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

4798
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
4799 4800 4801
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
4802

4803
            print(output_data[0].shape)
4804

4805 4806 4807 4808 4809 4810 4811 4812
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
4813

4814 4815
            #imperative mode
            import paddle.fluid.dygraph as dg
4816

4817 4818 4819 4820
            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)
4821

4822
                # [2L, 3L, 12L, 12L]
4823

4824
    """
4825
    resample_methods = {
4826
        'LINEAR': 'linear',
4827
        'BILINEAR': 'bilinear',
K
Kaipeng Deng 已提交
4828
        'TRILINEAR': 'trilinear',
4829
        'NEAREST': 'nearest',
4830
        'LINEAR': 'linear',
4831
    }
4832
    resample = resample.upper()
4833 4834
    if resample not in resample_methods:
        raise ValueError(
4835
            "The 'resample' of image_resize can only be 'LINEAR', 'BILINEAR', 'TRILINEAR' "
4836 4837
            "or 'NEAREST' currently."
        )
4838
    resample_type = resample_methods[resample]
4839

4840 4841 4842
    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 已提交
4843
        raise ValueError("'BILINEAR' and 'NEAREST' only support 4-D tensor.")
4844
    elif resample == 'TRILINEAR' and len(input.shape) != 5:
K
Kaipeng Deng 已提交
4845 4846
        raise ValueError("'TRILINEAR'only support 5-D tensor.")

4847 4848 4849 4850 4851
    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")

4852
    if out_shape is None and scale is None:
4853
        raise ValueError("One of out_shape and scale must not be None.")
4854
    helper = LayerHelper('{}_interp'.format(resample_type), **locals())
4855
    dtype = helper.input_dtype()
4856

4857
    if len(input.shape) == 3 and data_format not in ['NCW', 'NWC']:
4858
        raise ValueError(
4859 4860 4861 4862
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCW` or `NWC` supported for 3-D input."
        )
4863
    elif len(input.shape) == 4 and data_format not in ['NCHW', 'NHWC']:
4864
        raise ValueError(
4865 4866 4867 4868
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCHW` or `NHWC` supported for 4-D input."
        )
4869 4870
    elif len(input.shape) == 5 and data_format not in ['NCDHW', 'NDHWC']:
        raise ValueError(
4871 4872 4873 4874
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCDHW` or `NDHWC` supported for 5-D input."
        )
4875

4876
    def _is_list_or_turple_(data):
4877
        return isinstance(data, list) or isinstance(data, tuple)
4878

4879
    if data_format == 'NCHW' or data_format == 'NCDHW' or data_format == 'NCW':
4880
        data_layout = 'NCHW'
4881
    if data_format == 'NHWC' or data_format == 'NDHWC' or data_format == 'NWC':
4882 4883
        data_layout = 'NHWC'

4884
    inputs = {"X": input}
D
dengkaipeng 已提交
4885
    attrs = {
4886 4887 4888
        "out_d": -1,
        "out_h": -1,
        "out_w": -1,
D
dengkaipeng 已提交
4889 4890
        "interp_method": resample_type,
        "align_corners": align_corners,
4891
        "align_mode": align_mode,
4892
        "data_layout": data_layout,
D
dengkaipeng 已提交
4893 4894
    }

4895
    if out_shape is not None:
4896
        if isinstance(out_shape, Variable) and not _non_static_mode():
4897
            out_shape.stop_gradient = True
4898
            inputs['OutSize'] = out_shape
4899
        else:
4900 4901 4902 4903 4904 4905 4906 4907
            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]
4908
            if not (_is_list_or_turple_(out_shape)):
D
dengkaipeng 已提交
4909
                raise TypeError(
4910 4911
                    "out_shape should be a list or tuple or Variable."
                )
4912 4913 4914 4915 4916 4917
            # Validate the shape
            contain_var = False
            for dim_idx, dim_size in enumerate(out_shape):
                if isinstance(dim_size, Variable):
                    contain_var = True
                    continue
4918 4919 4920
                assert (
                    dim_size > 0
                ), "Each dimension size given in out_shape must be greater than 0."
4921 4922 4923 4924 4925 4926 4927 4928 4929 4930

            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:
4931
                        assert isinstance(dim, int)
4932
                        temp_out = helper.create_variable_for_type_inference(
4933 4934 4935 4936 4937
                            'int32'
                        )
                        fill_constant(
                            [1], 'int32', dim, force_cpu=True, out=temp_out
                        )
4938 4939 4940 4941
                        new_size_tensor.append(temp_out)
                        size_list.append(dim)
                inputs['SizeTensor'] = new_size_tensor

4942 4943
            if len(input.shape) == 3:
                if len(out_shape) != 1:
4944 4945 4946
                    raise ValueError(
                        "out_shape length should be 1 for " "input 3-D tensor."
                    )
4947 4948 4949 4950 4951 4952
                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 已提交
4953
                if len(out_shape) != 2:
4954 4955 4956
                    raise ValueError(
                        "out_shape length should be 2 for " "input 4-D tensor."
                    )
4957 4958 4959 4960 4961 4962 4963
                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 已提交
4964 4965
            if len(input.shape) == 5:
                if len(out_shape) != 3:
4966 4967 4968
                    raise ValueError(
                        "out_shape length should be 3 for " "input 5-D tensor."
                    )
4969 4970 4971 4972 4973 4974 4975 4976 4977
                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]
4978

4979
    else:
4980 4981 4982
        if _non_static_mode() and isinstance(scale, Variable):
            scale = scale.numpy()
        elif isinstance(scale, Variable):
4983 4984
            scale.stop_gradient = True
            inputs["Scale"] = scale
4985
        elif isinstance(scale, float) or isinstance(scale, int):
4986
            if scale <= 0:
4987
                raise ValueError("Attr(scale) should be greater than zero.")
4988
            attrs['scale'] = float(scale)
4989 4990
        else:
            raise TypeError(
4991 4992
                "Attr(scale)'s type should be float, int or Variable."
            )
4993

4994
    if isinstance(actual_shape, Variable):
4995 4996 4997 4998 4999
        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
5000 5001 5002
        inputs["OutSize"] = actual_shape
    elif actual_shape is not None:
        raise TypeError("actual_shape should either be Variable or None.")
5003 5004 5005 5006 5007 5008 5009 5010 5011

    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":
5012
            out = _legacy_C_ops.linear_interp(input, actual_shape, *dy_attr)
5013
        elif resample_type == "bilinear":
5014
            out = _legacy_C_ops.bilinear_interp(input, actual_shape, *dy_attr)
5015
        elif resample_type == "trilinear":
5016
            out = _legacy_C_ops.trilinear_interp(input, actual_shape, *dy_attr)
5017
        elif resample_type == "nearest":
5018
            out = _legacy_C_ops.nearest_interp(input, actual_shape, *dy_attr)
5019
        elif resample_type == "bicubic":
5020
            out = _legacy_C_ops.bicubic_interp(input, actual_shape, *dy_attr)
5021 5022
        return out

X
Xin Pan 已提交
5023
    out = helper.create_variable_for_type_inference(dtype)
5024 5025 5026 5027 5028 5029
    helper.append_op(
        type='{}_interp'.format(resample_type),
        inputs=inputs,
        outputs={"Out": out},
        attrs=attrs,
    )
5030
    return out
F
stash  
fengjiayi 已提交
5031 5032


5033
@templatedoc(op_type="bilinear_interp")
5034 5035 5036 5037 5038 5039 5040 5041 5042 5043
def resize_bilinear(
    input,
    out_shape=None,
    scale=None,
    name=None,
    actual_shape=None,
    align_corners=True,
    align_mode=1,
    data_format='NCHW',
):
5044
    """
5045

R
ruri 已提交
5046
    This op resizes the input by performing bilinear interpolation based on given
5047
    output shape which specified by actual_shape, out_shape and scale
5048 5049
    in priority order.

5050
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in
5051 5052
    the future and only use :attr:`out_shape` instead.

5053 5054 5055 5056
    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
5057 5058
    again in the other direction.

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

5062
    Align_corners and align_mode are optional parameters,the calculation
5063 5064 5065 5066
    method of interpolation can be selected by them.

    Example:

T
Tink_Y 已提交
5067
    .. code-block:: text
5068

T
Tink_Y 已提交
5069
        For scale:
5070

T
Tink_Y 已提交
5071
            if align_corners = True && out_size > 1 :
5072

T
Tink_Y 已提交
5073
              scale_factor = (in_size-1.0)/(out_size-1.0)
5074

T
Tink_Y 已提交
5075
            else:
5076

5077
              scale_factor = float(in_size/out_size)
5078

T
Tink_Y 已提交
5079 5080 5081 5082
        Bilinear interpolation:

          if:
              align_corners = False , align_mode = 0
5083

T
Tink_Y 已提交
5084 5085
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5086

T
Tink_Y 已提交
5087 5088
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5
5089

T
Tink_Y 已提交
5090
          else:
T
tink2123 已提交
5091

T
Tink_Y 已提交
5092 5093 5094 5095
              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}
5096

R
ruri 已提交
5097 5098
    Parameters:
        input(Variable): 4-D Tensor(NCHW), its data type is float32, float64, or uint8,
5099
                          its data format is specified by :attr:`data_format`.
D
dengkaipeng 已提交
5100
        out_shape(list|tuple|Variable|None): Output shape of resize bilinear
5101 5102
            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
5103
            Tensor Variable, its dimension size should be 1.
5104
        scale(float|Variable|None): The multiplier for the input height or width. At
5105 5106
             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 已提交
5107
             Default: None.
5108 5109 5110
        actual_shape(Variable): An optional input to specify output shape
                                dynamically. If provided, image resize
                                according to this given shape rather than
5111
                                :attr:`out_shape` and :attr:`scale` specifying
5112 5113
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
5114 5115 5116 5117 5118
                                :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 已提交
5119
                                errors would be occurred in graph constructing stage.
5120
                                Default: None
5121 5122
        align_corners(bool): ${align_corners_comment}
        align_mode(bool): ${align_mode_comment}
5123
        data_format (str, optional): Specify the data format of the input, and the data format of the output
5124 5125 5126
            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 已提交
5127
        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 已提交
5128 5129

    Returns:
5130
        Variable: 4-D tensor(NCHW or NHWC).
5131

5132 5133
    Examples:
        .. code-block:: python
5134

5135 5136 5137 5138 5139 5140
            #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 已提交
5141

5142 5143
            #1
            output = fluid.layers.resize_bilinear(input=input,out_shape=[12,12])
R
ruri 已提交
5144

5145 5146 5147 5148 5149
            #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 已提交
5150

5151 5152 5153 5154 5155
            #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 已提交
5156

5157 5158 5159 5160 5161
            #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 已提交
5162

5163 5164 5165
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5166

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

5169
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
5170 5171 5172
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
5173

5174
            print(output_data[0].shape)
5175

5176 5177 5178 5179 5180 5181 5182 5183
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
5184

5185 5186
            #imperative mode
            import paddle.fluid.dygraph as dg
5187

5188 5189 5190 5191
            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)
5192

5193
                # [2L, 3L, 12L, 12L]
5194

5195 5196
    """

5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'BILINEAR',
        actual_shape,
        align_corners,
        align_mode,
        data_format,
    )
5208 5209


K
Kaipeng Deng 已提交
5210
@templatedoc(op_type="trilinear_interp")
5211 5212 5213 5214 5215 5216 5217 5218 5219 5220
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 已提交
5221
    """
5222

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

5227
    **Warning:** the parameter :attr:`actual_shape` will be deprecated
5228 5229
    in the future and only use :attr:`out_shape` instead.

5230 5231 5232
    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 已提交
5233 5234 5235 5236 5237
    The linear interpolation is performed on three directions.

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

5238
    Align_corners and align_mode are optional parameters,the calculation
K
Kaipeng Deng 已提交
5239 5240 5241 5242 5243 5244 5245
    method of interpolation can be selected by them.

    Example:

    .. code-block:: text

        For scale:
5246

K
Kaipeng Deng 已提交
5247 5248 5249
            if align_corners = True && out_size > 1 :

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

K
Kaipeng Deng 已提交
5251
            else:
5252 5253

              scale_factor = float(in_size/out_size)
K
Kaipeng Deng 已提交
5254 5255 5256 5257

        Bilinear interpolation:

          if:
5258

K
Kaipeng Deng 已提交
5259
              align_corners = False , align_mode = 0
5260

K
Kaipeng Deng 已提交
5261 5262
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:
5263

K
Kaipeng Deng 已提交
5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276
              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 已提交
5277
    Parameters:
5278 5279
        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 已提交
5280
        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.
5281
        scale(float|Variable|None): The multiplier for the input depth, height or width.
5282 5283
             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 已提交
5284
             Default: None.
R
ruri 已提交
5285
        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 已提交
5286 5287 5288 5289 5290 5291
        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
5292 5293 5294 5295 5296
                                :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 已提交
5297
                                errors would be occurred in graph constructing stage.
K
Kaipeng Deng 已提交
5298 5299 5300
                                Default: None
        align_corners(bool): ${align_corners_comment}
        align_mode(bool): ${align_mode_comment}
5301
        data_format (str, optional): Specify the data format of the input, and the data format of the output
5302 5303 5304
            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 已提交
5305 5306

    Returns:
5307
        Variable: A 5-D Tensor(NCDHW or NDHWC)
K
Kaipeng Deng 已提交
5308 5309 5310

    Examples:
        .. code-block:: python
5311

5312 5313 5314 5315 5316 5317
            #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 已提交
5318

5319 5320
            #1
            output = fluid.layers.resize_trilinear(input=input,out_shape=[12,12,12])
R
ruri 已提交
5321

5322 5323 5324 5325 5326
            #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 已提交
5327

5328 5329 5330 5331 5332
            #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 已提交
5333

5334 5335 5336 5337 5338
            #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 已提交
5339

5340 5341 5342
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5343

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

5346
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
5347 5348 5349
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
5350

5351
            print(output_data[0].shape)
R
ruri 已提交
5352

5353 5354 5355 5356 5357 5358 5359 5360
            #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 已提交
5361

5362 5363
            #imperative mode
            import paddle.fluid.dygraph as dg
5364

5365 5366 5367 5368
            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)
5369

5370
                # [2L, 3L, 12L, 12L, 12L]
5371 5372 5373



K
Kaipeng Deng 已提交
5374 5375
    """

5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'TRILINEAR',
        actual_shape,
        align_corners,
        align_mode,
        data_format,
    )
K
Kaipeng Deng 已提交
5387 5388


5389
@templatedoc(op_type="nearest_interp")
5390 5391 5392 5393 5394 5395 5396 5397 5398
def resize_nearest(
    input,
    out_shape=None,
    scale=None,
    name=None,
    actual_shape=None,
    align_corners=True,
    data_format='NCHW',
):
5399
    """
5400

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

5405
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in the
5406 5407
    future and only use :attr:`out_shape` instead.

5408 5409
    Example:

T
Tink_Y 已提交
5410 5411 5412
    .. code-block:: text

        For scale:
5413

T
Tink_Y 已提交
5414 5415
            if align_corners = True && out_size > 1 :
              scale_factor = (in_size-1.0)/(out_size-1.0)
5416

T
Tink_Y 已提交
5417
            else:
5418

T
Tink_Y 已提交
5419
              scale_factor = float(in_size/out_size)
5420

T
Tink_Y 已提交
5421
        Nearest neighbor interpolation:
5422

T
Tink_Y 已提交
5423 5424
          if:
              align_corners = False
5425

T
Tink_Y 已提交
5426 5427
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5428

T
Tink_Y 已提交
5429 5430
              H_out = floor(H_{in} * scale_{factor})
              W_out = floor(W_{in} * scale_{factor})
5431

T
Tink_Y 已提交
5432 5433
          else:
              align_corners = True
5434

T
Tink_Y 已提交
5435 5436
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5437

T
Tink_Y 已提交
5438 5439
              H_out = round(H_{in} * scale_{factor})
              W_out = round(W_{in} * scale_{factor})
5440 5441


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

R
ruri 已提交
5445
    Parameters:
5446 5447
        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 已提交
5448
        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.
5449
        scale(float|Variable|None): The multiplier for the input height or width. At
5450 5451 5452
             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 已提交
5453
        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`
5454
        actual_shape(Variable): An optional input to specify output shape
5455 5456
                                dynamically. If provided, image resize
                                according to this given shape rather than
5457
                                :attr:`out_shape` and :attr:`scale` specifying
5458 5459
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
5460 5461 5462 5463 5464
                                :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 已提交
5465
                                errors would be occurred in graph constructing stage.
5466
                                Default: None
5467
        align_corners(bool): ${align_corners_comment}
5468
        data_format (str, optional): Specify the data format of the input, and the data format of the output
5469 5470 5471
            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 已提交
5472 5473

    Returns:
5474
        Variable: 4-D tensor(NCHW or NHWC).
5475 5476 5477

    Examples:
        .. code-block:: python
5478

5479 5480 5481 5482 5483
            #declarative mode
            import paddle.fluid as fluid
            import numpy as np
            import paddle
            paddle.enable_static()
5484

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

5487 5488
            #1
            output = fluid.layers.resize_nearest(input=input,out_shape=[12,12])
R
ruri 已提交
5489

5490 5491 5492 5493 5494
            #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 已提交
5495

5496 5497 5498 5499 5500
            #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 已提交
5501

5502 5503 5504 5505 5506
            #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 已提交
5507

5508 5509 5510
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5511

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

5514
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
5515 5516 5517
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
5518

5519
            print(output_data[0].shape)
R
ruri 已提交
5520

5521 5522 5523 5524 5525 5526 5527 5528
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
5529

5530 5531
            #imperative mode
            import paddle.fluid.dygraph as dg
5532

5533 5534 5535 5536
            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 已提交
5537

5538
                # [2L, 3L, 12L, 12L]
5539 5540 5541



5542 5543
    """

5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'NEAREST',
        actual_shape,
        align_corners,
        align_mode=1,
        data_format=data_format,
    )
5555 5556


5557
def log(x, name=None):
5558
    r"""
W
wanghaoshuang 已提交
5559 5560 5561 5562
    Calculates the natural log of the given input tensor, element-wise.

    .. math::

5563
        Out = \\ln(x)
W
wanghaoshuang 已提交
5564 5565

    Args:
S
Steffy-zxf 已提交
5566
        x (Tensor): Input Tensor. Must be one of the following types: float32, float64.
W
Wilber 已提交
5567
        name (str|None): The default value is None. Normally there is no need for user to set this property. For more information, please refer to :ref:`api_guide_Name`
5568

W
wanghaoshuang 已提交
5569 5570

    Returns:
S
Steffy-zxf 已提交
5571
        Tensor: The natural log of the input Tensor computed element-wise.
W
wanghaoshuang 已提交
5572 5573 5574 5575 5576

    Examples:

        .. code-block:: python

S
Steffy-zxf 已提交
5577
            import paddle
W
Wilber 已提交
5578

S
Steffy-zxf 已提交
5579 5580 5581 5582
            x = [[2,3,4], [7,8,9]]
            x = paddle.to_tensor(x, dtype='float32')
            res = paddle.log(x)
            # [[0.693147, 1.09861, 1.38629], [1.94591, 2.07944, 2.19722]]
W
wanghaoshuang 已提交
5583
    """
5584
    if in_dygraph_mode():
W
wanghuancoder 已提交
5585
        return _C_ops.log(x)
5586 5587
    if _in_legacy_dygraph():
        return _legacy_C_ops.log(x)
5588

5589
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], "log")
5590
    inputs = {'X': [x]}
W
wanghaoshuang 已提交
5591
    helper = LayerHelper('log', **locals())
W
wanghaoshuang 已提交
5592
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
5593
    out = helper.create_variable_for_type_inference(dtype)
W
wanghaoshuang 已提交
5594
    helper.append_op(type="log", inputs={"X": x}, outputs={"Out": out})
W
wanghaoshuang 已提交
5595 5596 5597
    return out


5598
@deprecated(since="2.0.0", update_to="paddle.nn.functional.relu")
5599
def relu(x, name=None):
W
wanghaoshuang 已提交
5600
    """
Z
zhupengyang 已提交
5601
    ${comment}
W
wanghaoshuang 已提交
5602 5603

    Args:
Z
zhupengyang 已提交
5604 5605 5606 5607
        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 已提交
5608 5609

    Returns:
Z
zhupengyang 已提交
5610
        Variable: ${out_comment}
W
wanghaoshuang 已提交
5611 5612 5613 5614 5615

    Examples:

        .. code-block:: python

5616
            import paddle.fluid as fluid
Z
zhupengyang 已提交
5617 5618 5619 5620 5621 5622 5623
            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. ]
5624
                #  [1.  2.6]]"""
5625 5626

    if in_dygraph_mode():
W
wanghuancoder 已提交
5627
        return _C_ops.relu(x)
5628 5629
    if _in_legacy_dygraph():
        return _legacy_C_ops.relu(x)
5630

5631 5632
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'relu')

5633
    inputs = {'X': [x]}
W
wanghaoshuang 已提交
5634
    helper = LayerHelper('relu', **locals())
W
wanghaoshuang 已提交
5635
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
5636
    out = helper.create_variable_for_type_inference(dtype)
5637 5638 5639
    helper.append_op(
        type="relu", inputs={"X": helper.input('x')}, outputs={"Out": out}
    )
W
wanghaoshuang 已提交
5640
    return out
5641 5642


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

Z
zhupengyang 已提交
5647
    prelu activation.
J
jerrywgz 已提交
5648

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

J
jerrywgz 已提交
5652 5653 5654 5655 5656 5657 5658 5659
    There are three modes for the activation:

    .. code-block:: text

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

Z
zhupengyang 已提交
5660 5661
    Parameters:
        x (Tensor): The input Tensor or LoDTensor with data type float32.
5662
        mode (str): The mode for weight sharing.
U
ustiniankw 已提交
5663 5664 5665
        param_attr (ParamAttr|None, optional): The parameter attribute for the learnable
            weight (alpha), it can be create by ParamAttr. None by default.
            For detailed information, please refer to :ref:`api_fluid_ParamAttr`.
5666 5667
        data_format(str, optional): Data format that specifies the layout of input.
            It may be "NC", "NCL", "NCHW", "NCDHW", "NLC", "NHWC" or "NDHWC". Default: "NCHW".
U
ustiniankw 已提交
5668 5669
        name (str, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.
J
jerrywgz 已提交
5670 5671

    Returns:
U
ustiniankw 已提交
5672
        Tensor, A tensor with the same shape and data type as x.
J
jerrywgz 已提交
5673 5674 5675 5676

    Examples:
        .. code-block:: python

5677
            import paddle
Z
zhupengyang 已提交
5678 5679 5680 5681 5682

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

J
jerrywgz 已提交
5684
    """
G
Guoxia Wang 已提交
5685
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'prelu')
5686

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

J
jerrywgz 已提交
5691 5692
    alpha_shape = [1]
    if mode == 'channel':
5693 5694

        true_data_format = [
5695 5696 5697 5698 5699 5700 5701
            'NC',
            'NCL',
            'NCHW',
            'NCDHW',
            'NLC',
            'NHWC',
            'NDHWC',
5702 5703 5704 5705
        ]
        if data_format not in true_data_format:
            raise ValueError(
                "data_format must be one of 'NC', 'NCL', 'NCHW', 'NCDHW', "
5706 5707
                "'NLC', 'NHWC', 'NDHWC' but receive {}".format(data_format)
            )
5708 5709 5710

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

5711 5712 5713 5714
        assert (
            len(x.shape) >= 2
        ), "The size of input shape should be equal or larger than 2 in prelu() when mode is 'channel'"
        # NOTE(zhiqiu): The alpha_shape should be [1, channel] + [1] * len(x.shape[2:]).
5715
        # To be consistent with Prelu, it is simplified.
5716 5717
        # NOTE(zhiqiu): Revert shape to [1, channel, 1, 1] for compatibility with saved model of old version.
        # NOTE(GuoxiaWang): support NHWC data format
5718
        if data_format == 'NHWC':
5719
            alpha_shape = [1, 1, 1, x.shape[-1]]
5720 5721 5722
        else:
            alpha_shape = [1, x.shape[1], 1, 1]

J
jerrywgz 已提交
5723
    elif mode == 'element':
5724 5725 5726
        assert (
            len(x.shape) >= 1
        ), "The size of input shape should be equal or larger than 1 in prelu() when mode is 'element'"
5727
        alpha_shape = [1] + list(x.shape)[1:]
J
jerrywgz 已提交
5728
    dtype = helper.input_dtype(input_param_name='x')
5729 5730 5731 5732 5733 5734 5735
    alpha = helper.create_parameter(
        attr=helper.param_attr,
        shape=alpha_shape,
        dtype=dtype,
        is_bias=False,
        default_initializer=Constant(0.25),
    )
5736 5737 5738
    if in_dygraph_mode():
        return _C_ops.prelu(x, alpha, data_format, mode)

X
Xin Pan 已提交
5739
    out = helper.create_variable_for_type_inference(dtype)
5740 5741 5742 5743 5744 5745
    helper.append_op(
        type="prelu",
        inputs={"X": x, 'Alpha': alpha},
        attrs={"mode": mode, "data_format": data_format},
        outputs={"Out": out},
    )
5746 5747 5748
    return out


G
fix  
gongweibao 已提交
5749 5750 5751
from paddle.fluid.framework import convert_np_dtype_to_dtype_


5752
@deprecated(since="2.0.0", update_to="paddle.normal")
G
gongweibao 已提交
5753
@templatedoc()
5754 5755 5756
def gaussian_random(
    shape, mean=0.0, std=1.0, seed=0, dtype='float32', name=None
):
G
fix  
gongweibao 已提交
5757
    """
5758 5759
    This OP returns a Tensor filled with random values sampled from a Gaussian
    distribution, with ``shape`` and ``dtype``.
G
fix  
gongweibao 已提交
5760 5761

    Args:
5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776
        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 已提交
5777 5778

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

5782
    Examples:
5783
       .. code-block:: python
5784

5785
            import paddle
5786
            import paddle.fluid as fluid
5787
            paddle.enable_static()
5788 5789

            # example 1:
5790
            # attr shape is a list which doesn't contain Tensor.
5791
            result_1 = fluid.layers.gaussian_random(shape=[3, 4])
5792 5793 5794
            # [[-0.31261674,  1.8736548,  -0.6274357,   0.96988016],
            #  [-0.12294637,  0.9554768,   1.5690808,  -1.2894802 ],
            #  [-0.60082096, -0.61138713,  1.5345167,  -0.21834975]]
5795 5796

            # example 2:
5797 5798 5799
            # 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)
5800
            result_2 = fluid.layers.gaussian_random(shape=[dim_1, dim_2])
5801 5802
            # [[ 0.51398206, -0.3389769,   0.23597084],
            #  [ 1.0388143,  -1.2015356,  -1.0499583 ]]
5803 5804

            # example 3:
5805
            # attr shape is a Tensor, the data type must be int64 or int32.
5806 5807
            var_shape = fluid.data(name='var_shape', shape=[2], dtype="int64")
            result_3 = fluid.layers.gaussian_random(var_shape)
5808 5809 5810 5811
            # if var_shape's value is [2, 3]
            # result_3 is:
            # [[-0.12310527,  0.8187662,   1.923219  ]
            #  [ 0.70721835,  0.5210541,  -0.03214082]]
5812

5813
       .. code-block:: python
5814

5815 5816
           # declarative mode
           # required: skiptest
5817 5818
           import numpy as np
           from paddle import fluid
5819

5820
           x = fluid.layers.gaussian_random((2, 3), std=2., seed=10)
5821

5822 5823 5824 5825
           place = fluid.CPUPlace()
           exe = fluid.Executor(place)
           start = fluid.default_startup_program()
           main = fluid.default_main_program()
5826

5827 5828
           exe.run(start)
           x_np, = exe.run(main, feed={}, fetch_list=[x])
5829

5830 5831 5832 5833 5834 5835 5836 5837 5838 5839
           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
5840

5841 5842 5843
           place = fluid.CPUPlace()
           with dg.guard(place) as g:
               x = fluid.layers.gaussian_random((2, 4), mean=2., dtype="float32", seed=10)
5844
               x_np = x.numpy()
5845 5846 5847
           x_np
           # array([[2.3060477 , 2.676496  , 3.9911983 , 0.9990833 ],
           #        [2.8675377 , 2.2279181 , 0.79029655, 2.8447366 ]], dtype=float32)
G
fix  
gongweibao 已提交
5848
    """
5849 5850
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
5851

5852 5853 5854
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
        place = _current_expected_place()
5855
        return _C_ops.gaussian(
5856 5857
            shape, float(mean), float(std), seed, dtype, place
        )
5858 5859

    if _in_legacy_dygraph():
5860
        shape = utils.convert_shape_to_list(shape)
5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872
        return _legacy_C_ops.gaussian_random(
            'shape',
            shape,
            'mean',
            float(mean),
            'std',
            float(std),
            'seed',
            seed,
            'dtype',
            dtype,
        )
5873 5874 5875

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

    inputs = {}
5878 5879 5880 5881
    attrs = {
        'mean': mean,
        'std': std,
        'seed': seed,
5882
        'dtype': dtype,
5883
        'use_mkldnn': False,
5884
    }
5885 5886 5887
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='gaussian_random/randn'
    )
5888

5889 5890
    helper = LayerHelper('gaussian_random', **locals())
    out = helper.create_variable_for_type_inference(dtype)
5891 5892 5893
    helper.append_op(
        type='gaussian_random', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
G
fix  
gongweibao 已提交
5894 5895 5896 5897

    return out


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

R
ruri 已提交
5903 5904 5905 5906
    Parameters:
        x (Variable): 2-D tensor, [batch_size, input_feature_dimensions]
        min (Float): minimum , default 0.0.
        max (Float): maximum, default 1.0.
5907
        seed (Float): Random seed, default 0. if seed is not 0, will generate same number every time.
G
fix  
gongweibao 已提交
5908
        dtype(np.dtype|core.VarDesc.VarType|str): The type of output data : float32, float_16, int etc
G
fix  
gongweibao 已提交
5909 5910

    Returns:
R
ruri 已提交
5911
        Variable: sampling tensor.
G
fix  
gongweibao 已提交
5912

5913 5914 5915
    Examples:
        .. code-block:: python

5916
            import paddle.fluid as fluid
R
ruri 已提交
5917
            x = fluid.data(
5918 5919
                name="X",
                shape=[13, 11],
R
ruri 已提交
5920
                dtype='float32')
5921

Y
Yibing Liu 已提交
5922
            out = fluid.layers.sampling_id(x)
G
fix  
gongweibao 已提交
5923 5924 5925
    """

    helper = LayerHelper('sampling_id', **locals())
X
Xin Pan 已提交
5926
    out = helper.create_variable_for_type_inference(dtype)
5927 5928 5929 5930 5931 5932
    helper.append_op(
        type='sampling_id',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'min': min, 'max': max, 'seed': seed},
    )
G
fix  
gongweibao 已提交
5933 5934 5935 5936

    return out


G
gongweibao 已提交
5937
@templatedoc()
X
Xin Pan 已提交
5938
def sum(x):
G
fix  
gongweibao 已提交
5939
    """
G
gongweibao 已提交
5940
    ${comment}
5941

5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970
    Case 1:
    ::
        Input:
            Input. Shape = [2, 3]
            Input = [[1, 2, 3],
                     [4, 5, 6]]

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

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

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

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

    Args:
5973
        x (Variable|list(Variable)): ${x_comment}
G
fix  
gongweibao 已提交
5974 5975

    Returns:
5976
        Variable: ${out_comment}
5977 5978 5979 5980

    Examples:
        .. code-block:: python

5981
            import paddle.fluid as fluid
5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000

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

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

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

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

S
Steffy-zxf 已提交
6006
    return paddle.add_n(x)
G
fix  
gongweibao 已提交
6007 6008 6009 6010


def shape(input):
    """
6011
    :alias_main: paddle.shape
6012 6013
        :alias: paddle.shape,paddle.tensor.shape,paddle.tensor.attribute.shape
        :old_api: paddle.fluid.layers.shape
6014

C
chengduozh 已提交
6015 6016
    **Shape Layer**

C
fix doc  
chengduozh 已提交
6017
    Get the shape of the input.
G
fix  
gongweibao 已提交
6018

6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035
    .. 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 已提交
6036
    Args:
6037
        input (Variable): The input can be N-D Tensor or SelectedRows with data type bool, float16, float32, float64, int32, int64.
6038
                          If input variable is type of SelectedRows, returns the shape of it's inner tensor.
G
fix  
gongweibao 已提交
6039 6040

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

6043 6044 6045
    Examples:
        .. code-block:: python

6046
            import paddle.fluid as fluid
6047
            import numpy as np
W
Wilber 已提交
6048 6049
            import paddle
            paddle.enable_static()
6050

6051
            inputs = fluid.data(name="x", shape=[3, 100, 100], dtype="float32")
6052 6053 6054 6055 6056 6057 6058 6059 6060
            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 已提交
6061
    """
6062
    if in_dygraph_mode():
6063
        out = _C_ops.shape(input)
6064 6065 6066
        out.stop_gradient = True
        return out
    if _in_legacy_dygraph():
6067
        out = _legacy_C_ops.shape(input)
W
Wilber 已提交
6068 6069 6070
        out.stop_gradient = True
        return out

6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085
    check_variable_and_dtype(
        input,
        'input',
        [
            'bool',
            'float16',
            'float32',
            'float64',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        'shape',
    )
G
fix  
gongweibao 已提交
6086
    helper = LayerHelper('shape', **locals())
6087
    out = helper.create_variable_for_type_inference(dtype='int32')
6088 6089 6090 6091 6092 6093
    helper.append_op(
        type='shape',
        inputs={'Input': input},
        outputs={'Out': out},
        stop_gradient=True,
    )
G
fix  
gongweibao 已提交
6094 6095

    return out
G
merge  
gongweibao 已提交
6096 6097


S
sneaxiy 已提交
6098 6099 6100 6101
def _elementwise_op(helper):
    op_type = helper.layer_type
    x = helper.kwargs.get('x', None)
    y = helper.kwargs.get('y', None)
X
Xin Pan 已提交
6102

S
sneaxiy 已提交
6103 6104
    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)
6105
    check_variable_and_dtype(
6106 6107 6108 6109 6110
        x,
        'x',
        ['float16', 'uint16', 'float32', 'float64', 'int32', 'int64'],
        op_type,
    )
6111
    check_variable_and_dtype(
6112 6113 6114 6115 6116
        y,
        'y',
        ['float16', 'uint16', 'float32', 'float64', 'int32', 'int64'],
        op_type,
    )
6117

S
sneaxiy 已提交
6118 6119
    axis = helper.kwargs.get('axis', -1)
    use_mkldnn = helper.kwargs.get('use_mkldnn', False)
S
sneaxiy 已提交
6120
    name = helper.kwargs.get('name', None)
6121
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
S
sneaxiy 已提交
6122

6123 6124 6125 6126 6127 6128
    helper.append_op(
        type=op_type,
        inputs={'X': x, 'Y': y},
        outputs={'Out': out},
        attrs={'axis': axis, 'use_mkldnn': use_mkldnn},
    )
S
sneaxiy 已提交
6129 6130 6131
    return helper.append_activation(out)


X
Xin Pan 已提交
6132
def elementwise_add(x, y, axis=-1, act=None, name=None):
6133
    """
6134

6135
    Examples:
6136

6137
        .. code-block:: python
6138

6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151
            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
6152

6153 6154 6155 6156
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6157

6158
            print(z_value) # [3., 8., 6.]
6159 6160


6161
        .. code-block:: python
6162

6163 6164 6165
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6166

6167 6168 6169 6170 6171 6172 6173 6174 6175 6176
            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
6177

6178 6179
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6180

6181 6182
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6183

6184
            print(z_value) # z.shape=[2,3,4,5]
6185 6186


6187
        ..  code-block:: python
6188

6189 6190 6191
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6192

6193 6194 6195 6196 6197 6198 6199 6200 6201 6202
            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
6203

6204 6205
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6206

6207 6208 6209
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
6210 6211

    """
J
Jiabin Yang 已提交
6212
    if _non_static_mode():
6213
        return _elementwise_op_in_dygraph(
6214 6215 6216 6217 6218
            x,
            y,
            axis=axis,
            act=act,
            op_name='elementwise_add',
6219 6220
            use_mkldnn=_global_flags()["FLAGS_use_mkldnn"],
        )
6221

S
sneaxiy 已提交
6222 6223 6224
    return _elementwise_op(LayerHelper('elementwise_add', **locals()))


6225
@deprecated(since="2.0.0", update_to="paddle.divide")
X
Xin Pan 已提交
6226
def elementwise_div(x, y, axis=-1, act=None, name=None):
6227
    """
6228

6229
    Examples:
6230

6231
        .. code-block:: python
6232

6233 6234 6235
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6236

6237 6238 6239 6240 6241 6242 6243 6244 6245 6246
            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
6247

6248 6249 6250 6251
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6252

6253
            print(z_value) # [2., 0.6, 2.]
6254 6255


6256
        .. code-block:: python
6257

6258 6259 6260
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6261

6262 6263 6264 6265 6266 6267 6268 6269 6270 6271
            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
6272

6273 6274
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6275

6276 6277
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6278

6279
            print(z_value) # z.shape=[2,3,4,5]
6280 6281


6282
        ..  code-block:: python
6283

6284 6285 6286
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6287

6288 6289 6290 6291 6292 6293 6294 6295 6296 6297
            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
6298

6299 6300
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6301

6302 6303 6304
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
6305 6306

    """
J
Jiabin Yang 已提交
6307
    if _non_static_mode():
6308 6309 6310
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_div'
        )
6311

S
sneaxiy 已提交
6312 6313 6314
    return _elementwise_op(LayerHelper('elementwise_div', **locals()))


X
Xin Pan 已提交
6315
def elementwise_sub(x, y, axis=-1, act=None, name=None):
6316
    """
6317

6318
    Examples:
6319

6320
        .. code-block:: python
6321

6322 6323 6324
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6325

6326 6327 6328 6329 6330 6331 6332 6333 6334 6335
            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
6336

6337 6338 6339 6340
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6341

6342
            print(z_value) # [1., -2., 2.]
6343 6344


6345
        .. code-block:: python
6346

6347 6348 6349
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6350

6351 6352 6353 6354 6355 6356 6357 6358 6359 6360
            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
6361

6362 6363
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6364

6365 6366
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6367

6368
            print(z_value) # z.shape=[2,3,4,5]
6369 6370


6371
        ..  code-block:: python
6372

6373 6374 6375
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6376

6377 6378 6379 6380 6381 6382 6383 6384 6385 6386
            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
6387

6388 6389
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6390

6391 6392 6393
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
6394 6395

    """
J
Jiabin Yang 已提交
6396
    if _non_static_mode():
6397 6398 6399
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_sub'
        )
6400

S
sneaxiy 已提交
6401 6402 6403
    return _elementwise_op(LayerHelper('elementwise_sub', **locals()))


6404
@deprecated(since="2.0.0", update_to="paddle.multiply")
X
Xin Pan 已提交
6405
def elementwise_mul(x, y, axis=-1, act=None, name=None):
6406
    """
6407

6408
    Examples:
6409

6410
        .. code-block:: python
6411

6412 6413 6414
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6415

6416 6417 6418 6419 6420 6421 6422 6423 6424 6425
            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
6426

6427 6428 6429 6430
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6431

6432
            print(z_value) # [2., 15., 8.]
6433 6434


6435
        .. code-block:: python
6436

6437 6438 6439
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6440

6441 6442 6443 6444 6445 6446 6447 6448 6449 6450
            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
6451

6452 6453
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6454

6455 6456
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6457

6458
            print(z_value) # z.shape=[2,3,4,5]
6459 6460


6461
        ..  code-block:: python
6462

6463 6464 6465
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6466

6467 6468 6469 6470 6471 6472 6473 6474 6475 6476
            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
6477

6478 6479
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6480

6481 6482 6483
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
6484

6485
    """
J
Jiabin Yang 已提交
6486
    if _non_static_mode():
6487 6488 6489
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_mul'
        )
6490

S
sneaxiy 已提交
6491 6492 6493 6494
    return _elementwise_op(LayerHelper('elementwise_mul', **locals()))


for func in [
6495 6496 6497 6498
    elementwise_add,
    elementwise_div,
    elementwise_sub,
    elementwise_mul,
6499 6500
]:
    op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
6501 6502

    # insert the c++ doc string on top of python doc string
6503 6504 6505 6506 6507
    func.__doc__ = (
        _generate_doc_string_(
            op_proto,
            additional_args_lines=[
                "axis (int32, optional): If X.dimension != Y.dimension, \
6508 6509
            Y.dimension must be a subsequence of x.dimension. \
            And axis is the start dimension index for broadcasting Y onto X. ",
6510
                "act (string, optional): Activation applied to the output. \
6511
            Default is None. Details: :ref:`api_guide_activations_en` ",
6512
                "name (string, optional): Name of the output. \
6513
            Default is None. It's used to print debug info for developers. Details: \
6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529
            :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__)
    )
6530

6531 6532 6533
    doc_list = func.__doc__.splitlines()

    for idx, val in enumerate(doc_list):
6534 6535 6536 6537 6538
        if (
            val.startswith("Warning: ")
            and val.endswith(" instead.")
            and "and will be removed in future versions." in val
        ):
6539 6540 6541 6542
            doc_list.insert(0, doc_list.pop(idx))
            func.__doc__ = "\n" + "\n".join(i for i in doc_list)
            break

6543
for func in []:
S
sneaxiy 已提交
6544 6545 6546 6547
    op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
    func.__doc__ = _generate_doc_string_(
        op_proto,
        additional_args_lines=[
S
sneaxiy 已提交
6548
            "act (basestring|None): Activation applied to the output.",
6549 6550 6551 6552 6553 6554
            "name (basestring|None): Name of the output.",
        ],
    )
    func.__doc__ = (
        func.__doc__
        + """
6555 6556 6557

Examples:
  .. code-block:: python
6558

6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588
    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)
6589 6590 6591 6592 6593 6594 6595 6596 6597 6598
    """
        % (
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
        )
    )
M
minqiyang 已提交
6599 6600


6601
def _logical_op(op_name, x, y, out=None, name=None, binary_op=True):
J
Jiabin Yang 已提交
6602
    if _non_static_mode():
6603
        op = getattr(_legacy_C_ops, op_name)
6604 6605 6606 6607
        if binary_op:
            return op(x, y)
        else:
            return op(x)
6608
    check_variable_and_dtype(
6609 6610
        x,
        "x",
6611
        ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
6612 6613
        op_name,
    )
6614
    if y is not None:
6615
        check_variable_and_dtype(
6616 6617
            y,
            "y",
6618
            ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
6619 6620
            op_name,
        )
6621
    if out is not None:
6622
        check_type(out, "out", Variable, op_name)
6623

M
minqiyang 已提交
6624 6625
    helper = LayerHelper(op_name, **locals())

6626 6627 6628
    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."
6629 6630
            % (op_name, x.dtype, y.dtype)
        )
M
minqiyang 已提交
6631 6632

    if out is None:
6633
        out = helper.create_variable_for_type_inference(dtype=x.dtype)
M
minqiyang 已提交
6634 6635

    if binary_op:
6636 6637 6638
        helper.append_op(
            type=op_name, inputs={"X": x, "Y": y}, outputs={"Out": out}
        )
M
minqiyang 已提交
6639 6640 6641 6642 6643 6644
    else:
        helper.append_op(type=op_name, inputs={"X": x}, outputs={"Out": out})

    return out


6645 6646 6647
@templatedoc()
def clip(x, min, max, name=None):
    """
6648
        :old_api: paddle.fluid.layers.clip
6649

6650 6651 6652 6653
    ${comment}

    Args:
        x(${x_type}): ${x_comment}
S
SunGaofeng 已提交
6654 6655
        min(float): ${min_comment}
        max(float): ${max_comment}
6656 6657
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
6658
                             For more information, please refer to :ref:`api_guide_Name`
6659 6660

    Returns:
S
SunGaofeng 已提交
6661 6662 6663 6664
        ${out_comment}

    Return Type:
        ${out_type}
6665 6666 6667 6668

    Examples:
        .. code-block:: python

S
SunGaofeng 已提交
6669
            import paddle.fluid as fluid
S
SunGaofeng 已提交
6670
            input = fluid.data(
6671 6672
                name='data', shape=[1], dtype='float32')
            reward = fluid.layers.clip(x=input, min=-1.0, max=1.0)
6673 6674 6675
    """

    helper = LayerHelper("clip", **locals())
6676
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'clip')
6677 6678

    if name is None:
6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692
        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},
    )
6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704

    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}
6705 6706 6707
        name(str, optional): For detailed information, please refer
            to :ref:`api_guide_Name`. Usually name is no need to set and
            None by default.
6708 6709

    Returns:
6710
        Tensor:
W
wangguanzhong 已提交
6711

6712
        out(${out_type}): ${out_comment}
6713

W
wangguanzhong 已提交
6714

6715 6716 6717
    Examples:
        .. code-block:: python

6718
            import paddle
6719
            import paddle.fluid as fluid
6720

6721 6722 6723
            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]]
6724 6725
    """

L
lyq 已提交
6726
    if in_dygraph_mode():
6727
        return _C_ops.clip_by_norm(x, max_norm)
J
Jiabin Yang 已提交
6728
    if _non_static_mode():
6729
        return _legacy_C_ops.clip_by_norm(x, 'max_norm', max_norm)
6730

6731
    helper = LayerHelper("clip_by_norm", **locals())
6732
    check_variable_and_dtype(x, 'X', ['float32', 'float16'], 'clip_by_norm')
6733
    check_type(max_norm, 'max_norm', (float), 'clip_by_norm')
6734 6735

    if name is None:
6736 6737 6738
        name = unique_name.generate_with_ignorable_key(
            ".".join([helper.name, 'tmp'])
        )
S
sneaxiy 已提交
6739

6740 6741 6742
    out = helper.create_variable(
        type=x.type, name=name, dtype=x.dtype, persistable=False
    )
6743

6744 6745 6746 6747 6748 6749
    helper.append_op(
        type="clip_by_norm",
        inputs={"X": x},
        attrs={"max_norm": max_norm},
        outputs={"Out": out},
    )
6750 6751

    return out
X
Xin Pan 已提交
6752 6753


6754
@deprecated(since="2.0.0", update_to="paddle.mean")
X
Xin Pan 已提交
6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765
@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}
6766 6767 6768 6769

    Examples:
        .. code-block:: python

6770
            import paddle
6771
            import paddle.fluid as fluid
6772 6773
            paddle.enable_static()

6774 6775
            input = fluid.layers.data(
                name='data', shape=[2, 3], dtype='float32')
6776
            mean = paddle.mean(input)
X
Xin Pan 已提交
6777
    """
6778

6779
    if _in_legacy_dygraph():
6780
        return _legacy_C_ops.mean(x)
6781
    if in_dygraph_mode():
6782
        return _C_ops.mean_all(x)
X
Xin Pan 已提交
6783 6784

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

6788 6789 6790
    helper.append_op(
        type="mean", inputs={"X": x}, attrs={}, outputs={"Out": out}
    )
X
Xin Pan 已提交
6791 6792 6793 6794

    return out


C
chengduo 已提交
6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805
@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}
6806 6807 6808 6809

    Examples:
        .. code-block:: python

6810
            import paddle.fluid as fluid
6811 6812 6813 6814 6815
            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 已提交
6816
    """
6817 6818 6819
    if in_dygraph_mode():
        return _C_ops.merge_selected_rows(x)

6820
    if _non_static_mode():
6821
        return _legacy_C_ops.merge_selected_rows(x)
C
chengduo 已提交
6822 6823 6824

    helper = LayerHelper("merge_selected_rows", **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
6825 6826 6827 6828 6829 6830
    helper.append_op(
        type="merge_selected_rows",
        inputs={"X": x},
        attrs={},
        outputs={"Out": out},
    )
C
chengduo 已提交
6831 6832 6833
    return out


X
Xin Pan 已提交
6834 6835
def mul(x, y, x_num_col_dims=1, y_num_col_dims=1, name=None):
    """
L
liu zhengxi 已提交
6836 6837 6838 6839 6840 6841 6842 6843
    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 已提交
6844 6845

    Args:
L
liu zhengxi 已提交
6846 6847
        x (Variable): The first input Tensor/LoDTensor of mul_op.
        y (Variable): The second input Tensor/LoDTensor of mul_op.
6848 6849 6850
        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 已提交
6851 6852

    Returns:
L
liu zhengxi 已提交
6853
        Variable(Tensor/LoDTensor): The output Tensor/LoDTensor of mul op.
6854 6855

    Examples:
L
liu zhengxi 已提交
6856
        ..  code-block:: python
6857

6858
            import paddle.fluid as fluid
6859 6860
            import paddle
            paddle.enable_static()
6861 6862 6863 6864 6865
            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)
6866

6867

X
Xin Pan 已提交
6868
    """
J
Jiabin Yang 已提交
6869
    if _non_static_mode():
6870 6871 6872 6873 6874 6875 6876 6877
        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 已提交
6878

6879 6880
    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 已提交
6881
    helper = LayerHelper("mul", **locals())
6882 6883
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'mul')
    check_variable_and_dtype(y, 'y', ['float16', 'float32', 'float64'], 'mul')
6884
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
X
Xin Pan 已提交
6885

6886 6887 6888
    helper.append_op(
        type="mul", inputs={"X": x, "Y": y}, attrs=attrs, outputs={"Out": out}
    )
X
Xin Pan 已提交
6889 6890 6891
    return out


M
minqiyang 已提交
6892 6893
def hash(input, hash_size, num_hash=1, name=None):
    """
6894

Z
zhupengyang 已提交
6895
    This OP hash the input to an integer less than the hash_size.
M
minqiyang 已提交
6896 6897
    The hash algorithm we used was xxHash - Extremely fast hash algorithm
    (https://github.com/Cyan4973/xxHash/tree/v0.6.5)
M
minqiyang 已提交
6898 6899

    Args:
Z
zhupengyang 已提交
6900 6901 6902 6903 6904 6905
        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 已提交
6906 6907

    Returns:
Z
zhupengyang 已提交
6908
       Variable: A LoDTensor with the same data type as input.
M
minqiyang 已提交
6909 6910

    Examples:
Z
zhupengyang 已提交
6911
        .. code-block:: python
H
haowang101779990 已提交
6912

6913
            import paddle.fluid as fluid
Z
zhupengyang 已提交
6914
            import numpy as np
6915 6916
            import paddle
            paddle.enable_static()
6917

Z
zhupengyang 已提交
6918
            place = fluid.core.CPUPlace()
6919

6920 6921
            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)
6922

Z
zhupengyang 已提交
6923 6924 6925 6926
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
            in1 = np.array([[1,2],[3,4]]).astype("int32")
            print(in1)
6927
            x_i = fluid.create_lod_tensor(in1, [[0, 2]], place)
Z
zhupengyang 已提交
6928 6929 6930 6931 6932 6933 6934 6935 6936 6937
            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 已提交
6938
    """
6939
    check_variable_and_dtype(input, 'input', ['int32', 'int64'], 'hash')
6940 6941
    check_type(hash_size, 'hash_size', int, 'hash')
    check_type(num_hash, 'num_hash', int, 'hash')
M
minqiyang 已提交
6942
    helper = LayerHelper('hash', **locals())
6943 6944 6945 6946 6947 6948 6949 6950 6951
    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 已提交
6952
    return out
G
gmcather 已提交
6953 6954


D
dengkaipeng 已提交
6955
@templatedoc()
6956 6957
def grid_sampler(x, grid, name=None):
    """
6958

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

H
haowang101779990 已提交
6968
    .. code-block:: text
6969

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

K
Kaipeng Deng 已提交
6973 6974 6975 6976
        .. code-block:: text

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

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

H
haowang101779990 已提交
6982 6983 6984 6985 6986 6987 6988 6989 6990
          wn ------- y_n ------- en
          |           |           |
          |          d_n          |
          |           |           |
         x_w --d_w-- grid--d_e-- x_e
          |           |           |
          |          d_s          |
          |           |           |
          ws ------- y_s ------- wn
6991

H
haowang101779990 已提交
6992 6993 6994 6995
        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
6996

H
haowang101779990 已提交
6997 6998 6999 7000
        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
7001

H
haowang101779990 已提交
7002 7003 7004 7005
        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
7006

H
haowang101779990 已提交
7007 7008
        output = wn * d_e * d_s + en * d_w * d_s
               + ws * d_e * d_n + es * d_w * d_n
D
dengkaipeng 已提交
7009 7010

    Args:
K
Kaipeng Deng 已提交
7011 7012 7013 7014 7015 7016 7017 7018 7019
        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 已提交
7020 7021

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

H
haowang101779990 已提交
7026 7027 7028 7029
    Examples:

        .. code-block:: python

K
Kaipeng Deng 已提交
7030
            import paddle.fluid as fluid
7031 7032
            import paddle.fluid as fluid
            import paddle
K
Kaipeng Deng 已提交
7033

7034
            paddle.enable_static()
K
Kaipeng Deng 已提交
7035 7036
            # use with affine_grid
            x = fluid.data(name='x', shape=[None, 10, 32, 32], dtype='float32')
K
Kaipeng Deng 已提交
7037 7038
            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 已提交
7039
            out = fluid.layers.grid_sampler(x=x, grid=grid)
7040

D
dengkaipeng 已提交
7041 7042 7043
    """
    helper = LayerHelper("grid_sampler", **locals())

7044
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'grid_sampler')
7045 7046 7047
    check_variable_and_dtype(
        grid, 'grid', ['float32', 'float64'], 'grid_sampler'
    )
D
dengkaipeng 已提交
7048 7049 7050 7051 7052 7053
    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")

7054
    out = helper.create_variable_for_type_inference(x.dtype)
D
dengkaipeng 已提交
7055 7056
    ipts = {'X': x, 'Grid': grid}

7057 7058
    attrs = {'use_cudnn': False} if core.is_compiled_with_rocm() else {}

7059 7060 7061
    helper.append_op(
        type='grid_sampler', inputs=ipts, outputs={'Output': out}, attrs=attrs
    )
7062 7063 7064
    return out


G
gmcather 已提交
7065
def log_loss(input, label, epsilon=1e-4, name=None):
7066
    r"""
7067

G
gmcather 已提交
7068 7069 7070 7071 7072 7073 7074
    **Negative Log Loss Layer**

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

    .. math::

7075 7076
        Out = -label * \log{(input + \epsilon)}
              - (1 - label) * \log{(1 - input + \epsilon)}
G
gmcather 已提交
7077 7078

    Args:
7079
        input (Tensor|list):  A 2-D tensor with shape [N x 1], where N is the
G
gmcather 已提交
7080
                                batch size. This input is a probability computed
Y
Yibing Liu 已提交
7081
                                by the previous operator. Data type float32.
7082
        label (Tensor|list):  The ground truth which is a 2-D tensor with
7083
                                shape [N x 1], where N is the batch size.
Y
Yibing Liu 已提交
7084 7085
                                Data type float32.
        epsilon (float, optional): A small number for numerical stability. Default 1e-4.
7086
        name(str|None): For detailed information, please refer to
Y
Yibing Liu 已提交
7087
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
G
gmcather 已提交
7088 7089

    Returns:
7090
        Tensor, which shape is [N x 1], data type is float32.
G
gmcather 已提交
7091 7092 7093 7094

    Examples:
        .. code-block:: python

7095 7096 7097 7098 7099 7100
          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 已提交
7101
    """
7102
    return paddle.nn.functional.log_loss(input, label, epsilon, name)
G
gmcather 已提交
7103 7104


7105 7106 7107
def bilinear_tensor_product(
    x, y, size, act=None, name=None, param_attr=None, bias_attr=None
):
7108
    r"""
7109 7110
    :api_attr: Static Graph

Y
Yibing Liu 已提交
7111
    **Bilinear Tensor Product Layer**
Q
Qiao Longfei 已提交
7112

Q
Qiao Longfei 已提交
7113
    This layer performs bilinear tensor product on two inputs.
Q
Qiao Longfei 已提交
7114 7115 7116
    For example:

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

Q
Qiao Longfei 已提交
7119
    In this formula:
7120 7121
      - :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 已提交
7122
      - :math:`W_{i}`: the i-th learned weight, shape is [M, N].
H
haowang101779990 已提交
7123
      - :math:`out_{i}`: the i-th element of out, shape is [batch_size, size].
Q
Qiao Longfei 已提交
7124 7125 7126
      - :math:`y^\mathrm{T}`: the transpose of :math:`y_{2}`.

    Args:
7127
        x (Variable): 2-D input tensor with shape [batch_size, M]. Data type
Y
Yibing Liu 已提交
7128
            is float32 or float64.
7129
        y (Variable): 2-D input tensor with shape [batch_size, N]. Data type
Y
Yibing Liu 已提交
7130
            should be same as **x**.
Q
Qiao Longfei 已提交
7131
        size (int): The dimension of this layer.
Y
Yibing Liu 已提交
7132
        act (str|None): Activation to be applied to the output of this layer. Default None.
7133
        name(str|None): For detailed information, please refer to
Y
Yibing Liu 已提交
7134
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
7135 7136
        param_attr (ParamAttr|None): To specify the weight parameter attribute.
            Default: None, which means the default weight parameter property is
Y
Yibing Liu 已提交
7137
            used. See usage for details in :ref:`api_fluid_ParamAttr` .
7138 7139
        bias_attr (ParamAttr|None): To specify the bias parameter attribute.
            Default: None, which means the default bias parameter property is
Y
Yibing Liu 已提交
7140
            used. See usage for details in :ref:`api_fluid_ParamAttr` .
Q
Qiao Longfei 已提交
7141
    Returns:
Y
Yibing Liu 已提交
7142
        Variable: A 2-D Tensor of shape [batch_size, size]. Data type is the same as input **x**.
Q
Qiao Longfei 已提交
7143 7144 7145 7146

    Examples:
        .. code-block:: python

7147 7148 7149 7150 7151
            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 已提交
7152 7153
    """
    helper = LayerHelper('bilinear_tensor_product', **locals())
Q
Qiao Longfei 已提交
7154
    dtype = helper.input_dtype('x')
Q
Qiao Longfei 已提交
7155 7156 7157

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

7158 7159 7160
    w = helper.create_parameter(
        attr=helper.param_attr, shape=param_shape, dtype=dtype, is_bias=False
    )
7161
    out = helper.create_variable_for_type_inference(dtype=dtype)
Q
Qiao Longfei 已提交
7162 7163 7164 7165

    inputs = {"X": x, "Y": y, "Weight": w}
    if helper.bias_attr:
        bias_size = [1, size]
7166 7167 7168
        bias = helper.create_parameter(
            attr=helper.bias_attr, shape=bias_size, dtype=dtype, is_bias=True
        )
Q
Qiao Longfei 已提交
7169
        inputs["Bias"] = bias
7170 7171 7172
    helper.append_op(
        type="bilinear_tensor_product", inputs=inputs, outputs={"Out": out}
    )
Q
Qiao Longfei 已提交
7173 7174 7175

    # add activation
    return helper.append_activation(out)
C
chengduo 已提交
7176 7177 7178 7179 7180


@templatedoc()
def get_tensor_from_selected_rows(x, name=None):
    """
7181 7182 7183 7184 7185 7186 7187 7188 7189
    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]]

7190
        Output is LoDTensor:
7191 7192 7193 7194 7195 7196
           out.shape = [5, 2]
           out.data = [[1, 1],
                       [2, 2],
                       [2, 2],
                       [3, 3],
                       [6, 6]]
C
chengduo 已提交
7197 7198

    Args:
7199 7200 7201
        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 已提交
7202 7203

    Returns:
7204
        Variable: LoDTensor transformed from SelectedRows. The data type is same with input.
B
bdzhuxiaoning 已提交
7205 7206 7207

    Examples:
        .. code-block:: python
7208

B
bdzhuxiaoning 已提交
7209 7210 7211 7212
            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 已提交
7213 7214
    """

7215 7216 7217 7218 7219
    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 已提交
7220 7221
    helper = LayerHelper('get_tensor_from_selected_rows', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
7222 7223 7224 7225 7226 7227
    helper.append_op(
        type='get_tensor_from_selected_rows',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={},
    )
C
chengduo 已提交
7228
    return out
7229 7230


7231
@templatedoc()
7232
def temporal_shift(x, seg_num, shift_ratio=0.25, name=None, data_format="NCHW"):
7233
    """
7234

7235
    **Temporal Shift Operator**
7236

7237
    ${comment}
7238 7239

    Args:
7240
        x(Tensor): ${x_comment}
7241
        seg_num(int): ${seg_num_comment}
D
dengkaipeng 已提交
7242
        shift_ratio(float): ${shift_ratio_comment}
K
Kaipeng Deng 已提交
7243 7244 7245
        name(str, optional): For detailed information, please refer
                             to :ref:`api_guide_Name`. Usually name is no need to set and
                             None by default.
7246 7247
        data_format(str, optional): Data format that specifies the layout of input.
            It can be "NCHW" or "NHWC". Default: "NCHW".
7248 7249

    Returns:
7250
        out(Tensor): The temporal shifting result is a tensor with the
K
Kaipeng Deng 已提交
7251
        same shape and same data type as the input.
7252 7253 7254 7255 7256 7257 7258

    Raises:
        TypeError: seg_num must be int type.

    Examples:
        .. code-block:: python

7259 7260 7261 7262
            import paddle
            import paddle.nn.functional as F

            input = paddle.randn([6, 4, 2, 2])
7263
            out = F.temporal_shift(x=input, seg_num=2, shift_ratio=0.2)
7264
    """
7265 7266 7267
    return paddle.nn.functional.temporal_shift(
        x, seg_num, shift_ratio, name, data_format
    )
7268 7269


7270
class PyFuncRegistry:
S
sneaxiy 已提交
7271 7272 7273
    _register_funcs = []

    def __init__(self, func):
S
sneaxiy 已提交
7274
        if func is None or not callable(func):
S
sneaxiy 已提交
7275 7276 7277
            raise TypeError('func must be a Python function')

        self._func = func
M
minqiyang 已提交
7278
        # find named args using reflection
7279
        args = inspect.getfullargspec(self._func)
S
sneaxiy 已提交
7280 7281 7282 7283 7284 7285
        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 已提交
7286 7287 7288
        '''
        Why record self here?

M
minqiyang 已提交
7289 7290
        1. For debug usage. Users can call
           :code:`py_func.registered_func(idx)` method
S
sneaxiy 已提交
7291
           to find the registered function corresponding
M
minqiyang 已提交
7292
           to :code:`idx`.
S
sneaxiy 已提交
7293

M
minqiyang 已提交
7294 7295
        2. For increasing reference count of self.
           It seems that to release Python object
S
sneaxiy 已提交
7296
           whose reference count is 1 would cause
M
minqiyang 已提交
7297
           segmentation fault error in C++ side.
S
sneaxiy 已提交
7298 7299
           May be lack of Python GC in C++ side?
        '''
S
sneaxiy 已提交
7300
        PyFuncRegistry._register_funcs.append(self)
S
sneaxiy 已提交
7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314

    @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 已提交
7315 7316 7317 7318 7319 7320 7321 7322 7323
        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 已提交
7324

S
sneaxiy 已提交
7325
        if not isinstance(func_ret, (list, tuple)):
7326
            func_ret = (func_ret,)
S
sneaxiy 已提交
7327 7328

        ret = []
S
sneaxiy 已提交
7329 7330 7331
        for each_ret in func_ret:
            if each_ret is None or isinstance(each_ret, core.LoDTensor):
                ret.append(each_ret)
S
sneaxiy 已提交
7332 7333
                continue

S
sneaxiy 已提交
7334 7335
            if not isinstance(each_ret, np.ndarray):
                each_ret = np.array(each_ret)
S
sneaxiy 已提交
7336

S
sneaxiy 已提交
7337 7338 7339
            tensor = core.LoDTensor()
            tensor.set(each_ret, core.CPUPlace())
            ret.append(tensor)
S
sneaxiy 已提交
7340

S
sneaxiy 已提交
7341
        return tuple(ret)
S
sneaxiy 已提交
7342 7343


7344
@static_only
S
sneaxiy 已提交
7345 7346 7347
@templatedoc()
def py_func(func, x, out, backward_func=None, skip_vars_in_backward_input=None):
    """
7348 7349
    :api_attr: Static Graph

7350 7351
    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
7352 7353
    other easily. So you can use Python and numpy API to register a python OP.

7354 7355
    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
7356
    call ``backward_func`` at backward runtime(if ``backward_func`` is not  None).
7357 7358
    ``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.
7359

7360
    The input of the backward function ``backward_func`` is ``x``, ``out`` and
7361 7362 7363
    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``.
7364

7365 7366
    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
7367 7368 7369 7370 7371 7372 7373
    ``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
7374 7375
            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
7376
            actively convert Tensor into a numpy array, so that we can use Python and
7377
            numpy API arbitrarily. If not, some operations of numpy may not be compatible.
7378 7379 7380 7381 7382 7383 7384
        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.
7385 7386 7387
        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
7388
            ``x`` when the network is at backward runtime.
7389 7390
        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].
7391
            It must belong to either ``x`` or ``out``. The default  value is None, which means
7392 7393
            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
7394
            useful when ``backward_func`` is not None.
7395 7396

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

    Examples:
7400
        .. code-block:: python
7401

7402
            # example 1:
7403
            import paddle
7404
            import numpy as np
7405

7406 7407 7408
            paddle.enable_static()

            # Creates a forward function, Tensor can be input directly without
7409
            # being converted into numpy array.
7410 7411 7412
            def tanh(x):
                return np.tanh(x)

7413
            # Skip x in backward function and return the gradient of x
7414
            # Tensor must be actively converted to numpy array, otherwise,
7415
            # operations such as +/- can't be used.
7416 7417
            def tanh_grad(y, dy):
                return np.array(dy) * (1 - np.square(np.array(y)))
7418

7419
            # Creates a forward function for debugging running networks(print value)
7420 7421
            def debug_func(x):
                print(x)
7422

7423
            def create_tmp_var(name, dtype, shape):
7424
                return paddle.static.default_main_program().current_block().create_var(
7425
                    name=name, dtype=dtype, shape=shape)
7426 7427 7428

            def simple_net(img, label):
                hidden = img
7429
                for idx in range(4):
7430
                    hidden = paddle.static.nn.fc(hidden, size=200)
7431 7432 7433
                    new_hidden = create_tmp_var(name='hidden_{}'.format(idx),
                        dtype=hidden.dtype, shape=hidden.shape)

7434
                    # User-defined forward and backward
7435
                    hidden = paddle.static.py_func(func=tanh, x=hidden,
7436 7437 7438
                        out=new_hidden, backward_func=tanh_grad,
                        skip_vars_in_backward_input=hidden)

7439
                    # User-defined debug functions that print out the input Tensor
7440
                    paddle.static.py_func(func=debug_func, x=hidden, out=None)
7441

7442
                prediction = paddle.static.nn.fc(hidden, size=10, activation='softmax')
7443 7444 7445 7446
                ce_loss = paddle.nn.loss.CrossEntropyLoss()
                return ce_loss(prediction, label)

            x = paddle.static.data(name='x', shape=[1,4], dtype='float32')
7447
            y = paddle.static.data(name='y', shape=[1], dtype='int64')
7448 7449 7450 7451 7452
            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')
7453
            input2 = np.random.randint(1, 10, size=[1], dtype='int64')
7454 7455 7456 7457 7458 7459
            out = exe.run(paddle.static.default_main_program(),
                          feed={'x':input1, 'y':input2},
                          fetch_list=[res.name])
            print(out)

        .. code-block:: python
7460

7461
            # example 2:
7462
            # This example shows how to turn Tensor into numpy array and
7463
            # use numpy API to register an Python OP
7464
            import paddle
7465 7466
            import numpy as np

7467 7468
            paddle.enable_static()

7469
            def element_wise_add(x, y):
7470
                # Tensor must be actively converted to numpy array, otherwise,
7471
                # numpy.shape can't be used.
7472
                x = np.array(x)
7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485
                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):
7486
                return paddle.static.default_main_program().current_block().create_var(
7487 7488 7489
                            name=name, dtype=dtype, shape=shape)

            def py_func_demo():
7490 7491
                start_program = paddle.static.default_startup_program()
                main_program = paddle.static.default_main_program()
7492 7493

                # Input of the forward function
7494 7495
                x = paddle.static.data(name='x', shape=[2,3], dtype='int32')
                y = paddle.static.data(name='y', shape=[2,3], dtype='int32')
7496

7497 7498 7499 7500
                # 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]
7501
                paddle.static.py_func(func=element_wise_add, x=[x,y], out=output)
7502

7503
                exe=paddle.static.Executor(paddle.CPUPlace())
7504 7505 7506 7507 7508
                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')
7509
                out = exe.run(main_program,
7510 7511 7512 7513 7514 7515 7516 7517 7518
                            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 已提交
7519
    """
S
sneaxiy 已提交
7520
    helper = LayerHelper('py_func', **locals())
7521
    check_type(x, 'X', (list, tuple, Variable, type(None)), 'py_func')
S
sneaxiy 已提交
7522 7523 7524
    if x is None:
        x = []
    elif isinstance(x, Variable):
S
sneaxiy 已提交
7525
        x = [x]
7526 7527 7528
    elif isinstance(x, tuple):
        x = list(x)
    elif not isinstance(x, (list, tuple, Variable)):
S
sneaxiy 已提交
7529
        raise TypeError('Input must be Variable/list(Variable)/tuple(Variable)')
7530
    check_type(out, 'Out', (list, tuple, Variable, type(None)), 'py_func')
S
sneaxiy 已提交
7531 7532 7533
    if out is None:
        out_list = []
    elif isinstance(out, Variable):
S
sneaxiy 已提交
7534
        out_list = [out]
7535 7536
    elif isinstance(out, tuple):
        out_list = list(out)
7537 7538 7539
    elif isinstance(out, list):
        out_list = out
    else:
S
sneaxiy 已提交
7540
        raise TypeError(
7541 7542
            'Output must be Variable/list(Variable)/tuple(Variable)'
        )
S
sneaxiy 已提交
7543

S
sneaxiy 已提交
7544
    fwd_func_id = PyFuncRegistry(func).id
7545 7546 7547
    bwd_func_id = (
        PyFuncRegistry(backward_func).id if backward_func is not None else -1
    )
S
sneaxiy 已提交
7548 7549

    for each_out in out_list:
S
sneaxiy 已提交
7550 7551
        if len(each_out.shape) == 0:
            raise ValueError(
S
sneaxiy 已提交
7552 7553
                'Output shapes of py_func op should be provided by users manually'
            )
S
sneaxiy 已提交
7554

S
sneaxiy 已提交
7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566
    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(
7567 7568 7569 7570
                    'Variable {} is not found in forward inputs and outputs'.format(
                        v.name
                    )
                )
S
sneaxiy 已提交
7571
            backward_skip_vars.add(v.name)
S
sneaxiy 已提交
7572

7573 7574 7575 7576 7577 7578 7579 7580 7581 7582
    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 已提交
7583
    return out
S
sneaxiy 已提交
7584 7585 7586


# For debug usage
S
sneaxiy 已提交
7587 7588 7589 7590
py_func.registered_func = PyFuncRegistry.registered_func
py_func.registered_func_num = PyFuncRegistry.registered_func_num


R
ruri 已提交
7591 7592 7593
def pixel_shuffle(x, upscale_factor):
    """

R
ruri 已提交
7594
    This op rearranges elements in a tensor of shape [N, C, H, W]
R
ruri 已提交
7595 7596 7597
    to a tensor of shape [N, C/r**2, H*r, W*r].
    This is useful for implementing efficient sub-pixel convolution
    with a stride of 1/r.
7598
    Please refer to the paper: `Real-Time Single Image and Video Super-Resolution
R
ruri 已提交
7599 7600 7601
    Using an Efficient Sub-Pixel Convolutional Neural Network <https://arxiv.org/abs/1609.05158v2>`_ .
    by Shi et. al (2016) for more details.

R
ruri 已提交
7602
    Parameters:
R
ruri 已提交
7603

R
ruri 已提交
7604 7605
        x(Variable): 4-D tensor, the data type should be float32 or float64.
        upscale_factor(int): factor to increase spatial resolution.
R
ruri 已提交
7606 7607

    Returns:
7608
        Out(Variable): Reshaped tensor according to the new dimension.
R
ruri 已提交
7609 7610 7611 7612 7613 7614 7615

    Raises:
        ValueError: If the square of upscale_factor cannot divide the channels of input.

    Examples:
        .. code-block:: python

7616 7617 7618 7619 7620 7621 7622 7623
            # declarative mode
            import paddle.fluid as fluid
            import numpy as np
            input = fluid.data(name="input", shape=[2,9,4,4])
            output = fluid.layers.pixel_shuffle(x=input, upscale_factor=3)
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
7624

7625 7626
            input_data = np.random.rand(2,9,4,4).astype("float32")
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
7627 7628 7629
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
7630

7631 7632
            # print(output.shape)
            # (2L, 1L, 12L, 12L)
R
ruri 已提交
7633 7634 7635

    """

R
ruri 已提交
7636
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'pixel_shuffle')
R
ruri 已提交
7637 7638 7639 7640 7641 7642 7643
    helper = LayerHelper("pixel_shuffle", **locals())

    out = helper.create_variable_for_type_inference(dtype=x.dtype)

    if not isinstance(upscale_factor, int):
        raise TypeError("upscale factor must be int type")

7644 7645 7646 7647 7648 7649
    helper.append_op(
        type="pixel_shuffle",
        inputs={"X": x},
        outputs={"Out": out},
        attrs={"upscale_factor": upscale_factor},
    )
R
ruri 已提交
7650 7651 7652
    return out


7653 7654 7655 7656 7657
def fsp_matrix(x, y):
    """

    **FSP matrix op**

7658
    This op is used to calculate the flow of solution procedure (FSP) matrix of two 4-D Tensor feature maps.
7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669
    Given feature map x with shape [x_channel, h, w] and feature map y with shape
    [y_channel, h, w], we can get the fsp matrix of x and y in two steps:

    1. reshape x into matrix with shape [x_channel, h * w] and reshape and
       transpose y into matrix with shape [h * w, y_channel].
    2. multiply x and y to get fsp matrix with shape [x_channel, y_channel].

    The output is a batch of fsp matrices.

    Args:

7670 7671 7672
        x (Variable): A 4-D Tensor feature map with shape [batch_size, x_channel, height, width].
                      A Tensor with type float32, float64.
        y (Variable): A 4-D Tensor feature map with shape [batch_size, y_channel, height, width].
7673
                      The y_channel can be different with the x_channel of Input(X)
7674 7675
                      while the other dimensions must be the same with Input(X)'s. A Tensor with
                      type float32, float64.
7676 7677 7678 7679

    Returns:

        fsp matrix (Variable): The output of FSP op with shape [batch_size, x_channel, y_channel].
7680 7681
        The x_channel is the channel of x and the y_channel is the channel of y. A Tensor with
        type float32, float64.
7682 7683 7684 7685 7686

    Examples:

        .. code-block:: python

B
Bai Yifan 已提交
7687
            import paddle.fluid as fluid
B
Bai Yifan 已提交
7688
            data = fluid.data(name='data', shape=[None, 3, 32, 32])
B
Bai Yifan 已提交
7689 7690 7691 7692
            feature_map_0 = fluid.layers.conv2d(data, num_filters=2,
                                                filter_size=3)
            feature_map_1 = fluid.layers.conv2d(feature_map_0, num_filters=2,
                                                filter_size=1)
7693 7694 7695
            loss = fluid.layers.fsp_matrix(feature_map_0, feature_map_1)

    """
7696 7697
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'fsp_matrix')
    check_variable_and_dtype(y, 'y', ['float32', 'float64'], 'fsp_matrix')
7698
    helper = LayerHelper('fsp_matrix', **locals())
7699 7700 7701
    out = helper.create_variable_for_type_inference(
        dtype=helper.input_dtype(input_param_name='x')
    )
7702 7703
    helper.append_op(type='fsp', inputs={'X': x, 'Y': y}, outputs={'Out': out})
    return out
H
heqiaozhi 已提交
7704 7705 7706


def continuous_value_model(input, cvm, use_cvm=True):
7707
    r"""
H
fix doc  
heqiaozhi 已提交
7708

H
heqiaozhi 已提交
7709
    **continuous_value_model layers**
H
fix doc  
heqiaozhi 已提交
7710

Z
zhoushiyu 已提交
7711
    Now, this OP is used in CTR project to remove or dispose show and click value in :attr:`input`.
H
fix doc  
heqiaozhi 已提交
7712

Z
zhoushiyu 已提交
7713 7714
    :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 已提交
7715
    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 已提交
7716 7717
    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 已提交
7718

Z
zhoushiyu 已提交
7719 7720 7721 7722 7723 7724 7725
    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 已提交
7726

H
heqiaozhi 已提交
7727
    Returns:
H
fix doc  
heqiaozhi 已提交
7728

Z
zhoushiyu 已提交
7729 7730
        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 已提交
7731

H
heqiaozhi 已提交
7732
    Examples:
H
fix doc  
heqiaozhi 已提交
7733

H
heqiaozhi 已提交
7734
        .. code-block:: python
H
fix doc  
heqiaozhi 已提交
7735

7736
          import paddle.fluid as fluid
Z
zhoushiyu 已提交
7737 7738
          input = fluid.data(name="input", shape=[64, 1], dtype="int64")
          label = fluid.data(name="label", shape=[64, 1], dtype="int64")
H
heqiaozhi 已提交
7739 7740 7741 7742 7743 7744 7745 7746
          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 已提交
7747

H
heqiaozhi 已提交
7748 7749 7750
    """
    helper = LayerHelper('cvm', **locals())
    out = helper.create_variable(dtype=input.dtype)
7751 7752 7753 7754 7755 7756 7757 7758 7759
    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 已提交
7760
    return out
Z
zhoukunsheng 已提交
7761 7762 7763 7764 7765 7766 7767


def where(condition):
    """
    Return an int64 tensor with rank 2, specifying the coordinate of true element in `condition`.

    Args:
7768
        condition(Variable): A bool tensor with rank at least 1, the data type is bool.
Z
zhoukunsheng 已提交
7769 7770

    Returns:
7771
        Variable, the output data type is int64. : The tensor variable storing a 2-D tensor, which involves all coordinate.
Z
zhoukunsheng 已提交
7772 7773 7774 7775

    Examples:
        .. code-block:: python

7776
             import paddle.fluid as fluid
7777 7778 7779
             import paddle.fluid.layers as layers
             import numpy as np

Z
zhoukunsheng 已提交
7780
             # condition is a tensor [True, False, True]
7781 7782 7783
             condition = layers.assign(np.array([1, 0, 1], dtype='int32'))
             condition = layers.cast(condition, 'bool')
             out = layers.where(condition) # [[0], [2]]
Z
zhoukunsheng 已提交
7784 7785

             # condition is a tensor [[True, False], [False, True]]
7786 7787 7788
             condition = layers.assign(np.array([[1, 0], [0, 1]], dtype='int32'))
             condition = layers.cast(condition, 'bool')
             out = layers.where(condition) # [[0, 0], [1, 1]]
Z
zhoukunsheng 已提交
7789 7790

             # condition is a tensor [False, False, False]
7791 7792 7793 7794
             condition = layers.assign(np.array([0, 0, 0], dtype='int32'))
             condition = layers.cast(condition, 'bool')
             out = layers.where(condition) # [[]]

Z
zhoukunsheng 已提交
7795
    """
H
hong 已提交
7796 7797

    if in_dygraph_mode():
7798
        return _C_ops.nonzero(condition)
7799 7800
    if _in_legacy_dygraph():
        return _legacy_C_ops.where_index(condition)
7801

W
wanghuancoder 已提交
7802 7803
    helper = LayerHelper("where_index", **locals())

Z
zhoukunsheng 已提交
7804
    out = helper.create_variable_for_type_inference(
7805 7806 7807 7808 7809 7810 7811 7812
        dtype=core.VarDesc.VarType.INT64
    )

    helper.append_op(
        type='where_index',
        inputs={'Condition': condition},
        outputs={'Out': [out]},
    )
Z
zhoukunsheng 已提交
7813
    return out
Z
zhoukunsheng 已提交
7814 7815


W
WangXi 已提交
7816
@deprecated(since="2.0.0", update_to="paddle.sign")
Z
zhoukunsheng 已提交
7817
def sign(x):
7818
    r"""
7819
    This OP returns sign of every element in `x`: 1 for positive, -1 for negative and 0 for zero.
Z
zhoukunsheng 已提交
7820 7821

    Args:
7822 7823
        x(Variable|numpy.ndarray): The input variable could be N-D tensor or N-D numpy array, \
            the input data type is float32 or float64.
Z
zhoukunsheng 已提交
7824 7825

    Returns:
7826
        Variable, the output data type is the same as input data type. : The output sign tensor with identical shape to input :attr:`x`.
Z
zhoukunsheng 已提交
7827 7828 7829 7830

    Examples:
        .. code-block:: python

7831 7832 7833
          import paddle.fluid as fluid
          import numpy as np

7834
          # [1.0, 0.0, -1.0]
7835
          data = fluid.layers.sign(np.array([3.0, 0.0, -2.0], dtype='float32'))
Z
zhoukunsheng 已提交
7836 7837 7838
    """

    helper = LayerHelper("sign", **locals())
7839 7840 7841 7842
    check_type(x, 'x', (Variable, np.ndarray), 'sign')
    if isinstance(x, np.ndarray):
        x = assign(x)
    check_dtype(x.dtype, 'x', ['float16', 'float32', 'float64'], 'sign')
Z
zhoukunsheng 已提交
7843 7844 7845 7846 7847
    out = helper.create_variable_for_type_inference(dtype=x.dtype)

    helper.append_op(type='sign', inputs={'X': [x]}, outputs={'Out': [out]})

    return out
7848 7849


Z
zhoukunsheng 已提交
7850
def unique(x, dtype='int32'):
7851
    r"""
Z
zhoukunsheng 已提交
7852 7853 7854
    Return a unique tensor for `x` and an index tensor pointing to this unique tensor.

    Args:
Z
Zhang Ting 已提交
7855 7856
        x(Tensor): A 1-D input tensor, it's data type should be float32, float64, int32, int64.
        dtype(np.dtype|str, optional): The type of index tensor: int32, int64. Default: int32.
Z
zhoukunsheng 已提交
7857 7858 7859 7860 7861 7862 7863 7864 7865 7866

    Returns:
        tuple: (out, index). `out` is the unique tensor for `x`, with identical dtype to `x`, and \
            `index` is an index tensor pointing to `out`, by which user can recover the original `x` tensor.

    Examples:
        .. code-block:: python

             import numpy as np
             import paddle.fluid as fluid
W
wawltor 已提交
7867
             x = fluid.layers.assign(np.array([2, 3, 3, 1, 5, 3], dtype='int32'))
Z
zhoukunsheng 已提交
7868 7869 7870
             out, index = fluid.layers.unique(x) # out is [2, 3, 1, 5]; index is [0, 1, 1, 2, 3, 1]
    """

7871 7872 7873
    check_variable_and_dtype(
        x, "x", ['float32', 'float64', 'int32', 'int64'], "unique"
    )
Z
zhoukunsheng 已提交
7874 7875 7876 7877 7878 7879
    helper = LayerHelper("unique", **locals())

    out = helper.create_variable_for_type_inference(dtype=x.dtype)

    index = helper.create_variable_for_type_inference(dtype)

7880 7881 7882 7883 7884 7885
    helper.append_op(
        type='unique',
        inputs={'X': x},
        attrs={'dtype': convert_np_dtype_to_dtype_(dtype)},
        outputs={'Out': [out], 'Index': [index]},
    )
Z
zhoukunsheng 已提交
7886 7887 7888 7889

    return out, index


7890
def unique_with_counts(x, dtype='int32'):
7891
    r"""
T
tianshuo78520a 已提交
7892
    This OP return a unique tensor for `x` , and count tensor that the count of unique result in raw input, \
7893
    and an index tensor pointing to this unique tensor.
7894

7895
    **NOTICE**: This op support the variable type of Tensor only.
7896 7897

    Args:
7898
        x(Variable): A 1-D input tensor with input shape of :math:`[N]` , the input data type is float32, float64, int32, int64.
7899
        dtype(np.dtype|core.VarDesc.VarType|str): The type of count and index tensor, it could be int32, int64. Default value is int32.
7900

7901
    Returns:
7902 7903 7904
        tuple, the variable type in tuple is Tensor, the output :attr:`out` data type is the same as input :attr:`x`, \
        and data type of output :attr:`index` and :attr:`count` will be int32 or int64.: The :attr:`out` is unique tensor for input :attr:`x`,\
        the data shape is :math:`[K]`, the `K` may be different to the `N` in shape of :attr:`x`. :attr:`index` is an index tensor pointing\
T
tianshuo78520a 已提交
7905
        to :attr:`out`, the data shape is :math:`[N]` , the data shape is the same as input :attr:`x`. :attr:`count` is count of unique element in\
7906
        the :attr:`x`, the data shape is :math:`[K]`, the data shape is the same as output :attr:`out`.
7907 7908 7909 7910 7911 7912 7913 7914 7915

    Examples:
        .. code-block:: python

             import numpy as np
             import paddle.fluid as fluid
             x = fluid.layers.assign(np.array([2, 3, 3, 1, 5, 3], dtype='int32'))
             out, index, count = fluid.layers.unique_with_counts(x) # out is [2, 3, 1, 5]; index is [0, 1, 1, 2, 3, 1]
                                                        # count is [1, 3, 1, 1]
7916
            # x.shape=(6,) out.shape=(4,), index.shape=(6,), count.shape=(4,)
7917
    """
7918 7919 7920
    check_variable_and_dtype(
        x, "x", ['float32', 'float64', 'int32', 'int64'], "unique_with_counts"
    )
7921 7922
    if not (dtype == 'int32' or dtype == 'int64'):
        raise TypeError(
7923 7924
            "Op unique_with_counts, index dtype must be int32 or int64"
        )
7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938

    if x is None or len(x.shape) != 1:
        raise ValueError(
            "Op unique_with_counts, x must not be null and size of dim must be 1"
        )

    helper = LayerHelper("unique_with_counts", **locals())

    out = helper.create_variable_for_type_inference(dtype=x.dtype)

    index = helper.create_variable_for_type_inference(dtype)

    count = helper.create_variable_for_type_inference(dtype)

7939 7940 7941 7942 7943 7944
    helper.append_op(
        type='unique_with_counts',
        inputs={'X': x},
        attrs={'dtype': convert_np_dtype_to_dtype_(dtype)},
        outputs={'Out': [out], 'Index': [index], 'Count': [count]},
    )
7945 7946 7947 7948

    return out, index, count


7949
def unfold(x, kernel_sizes, strides=1, paddings=0, dilations=1, name=None):
7950
    r"""
7951

S
SunGaofeng 已提交
7952
    This op returns a col buffer of sliding local blocks of input x, also known
7953
    as im2col for batched 2D image tensors. For each block under the convolution filter,
T
tianshuo78520a 已提交
7954
    all element will be rearranged as a column. While the convolution filter sliding over
7955 7956
    the input feature map, a series of such columns will be formed.

S
SunGaofeng 已提交
7957
    For each input :math:`x` with shape [N, C, H, W], the output shape [N, Cout, Lout]
7958 7959 7960 7961
    can be calculated as following.

    .. math::

7962
        dkernel[0] &= dilations[0] \times (kernel\_sizes[0] - 1) + 1
7963

7964
        dkernel[1] &= dilations[1] \times (kernel\_sizes[1] - 1) + 1
7965

7966
        hout &= \frac{H + paddings[0] + paddings[2] - dkernel[0]}{strides[0]} + 1
7967

7968
        wout &= \frac{W + paddings[1] + paddings[3] - dkernel[1]}{strides[1]} + 1
7969

7970
        Cout &= C \times kernel\_sizes[0] \times kernel\_sizes[1]
7971

7972
        Lout &= hout \times wout
7973 7974


S
SunGaofeng 已提交
7975
    Parameters:
7976
        x(Tensor):              4-D Tensor, input tensor of format [N, C, H, W],
S
SunGaofeng 已提交
7977
                                  data type can be float32 or float64
7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989
        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 已提交
7990
        dilations(int|list):      the dilations of convolution kernel, should be
T
tianshuo78520a 已提交
7991
                                  [dilation_h, dilation_w], or an integer dilation treated as
7992
                                  [dilation, dilation]. For default, it will be [1, 1].
7993 7994
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
7995
                             For more information, please refer to :ref:`api_guide_Name`
7996

7997

7998
    Returns:
7999
        The tensor corresponding to the sliding local blocks.
8000 8001 8002
        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 已提交
8003 8004 8005
        The data type of output is the same as the input :math:`x`

    Return Type:
8006
        Tensor
8007 8008 8009 8010 8011

    Examples:

        .. code-block:: python

8012 8013 8014 8015 8016
            import paddle
            import paddle.nn.functional as F

            x = paddle.randn((100,3,224,224))
            y = F.unfold(x, [3, 3], 1, 1, 1)
8017 8018
    """

8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038
    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,
):
8039
    r"""
8040

8041
    Deformable ROI Pooling Layer
8042

8043
    Performs deformable region-of-interest pooling on inputs. As described
8044
    in `Deformable Convolutional Networks <https://arxiv.org/abs/1703.06211>`_, it will get offset for each bin after
8045
    roi pooling so that pooling at correct region. Batch_size will change to the number of region bounding boxes after deformable_roi_pooling.
8046

8047
    The operation has three steps:
8048

8049
    1. Dividing each region proposal into equal-sized sections with the pooled_width and pooled_height.
8050

8051 8052
    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.
8053

8054
    3. Sample several points in each bin to get average values as output.
8055 8056


8057 8058 8059 8060 8061 8062 8063 8064 8065
    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.
8066 8067 8068
        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.
8069 8070 8071 8072
        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.
8073
        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
8074
                          is k1 * k2 * (C + 1), which k1 and k2 are group width and height and C+1 is number of output
T
tianshuo78520a 已提交
8075
                          channels.) eg.(4, 6), which 4 is height of group and 6 is width of group. Default: [1, 1].
8076 8077 8078 8079 8080 8081 8082
        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 已提交
8083
                                   If value is True, input dimension should be output dimension * pooled_height * pooled_width. Default: False.
8084 8085 8086 8087
        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 已提交
8088 8089 8090 8091

    Examples:
      .. code-block:: python

8092 8093
        # position_sensitive=True
        import paddle.fluid as fluid
C
chengjuntao 已提交
8094
        input = fluid.data(name="input",
8095 8096
                           shape=[2, 192, 64, 64],
                           dtype='float32')
C
chengjuntao 已提交
8097 8098
        rois = fluid.data(name="rois",
                          shape=[-1, 4],
8099
                          dtype='float32',
C
chengjuntao 已提交
8100 8101
                          lod_level=1)
        trans = fluid.data(name="trans",
8102 8103 8104 8105 8106
                           shape=[2, 384, 64, 64],
                           dtype='float32')
        x = fluid.layers.deformable_roi_pooling(input=input,
                                                rois=rois,
                                                trans=trans,
C
chengjuntao 已提交
8107
                                                no_trans=False,
8108
                                                spatial_scale=1.0,
C
chengjuntao 已提交
8109 8110 8111 8112
                                                group_size=(1, 1),
                                                pooled_height=8,
                                                pooled_width=8,
                                                part_size=(8, 8),
8113
                                                sample_per_part=4,
C
chengjuntao 已提交
8114 8115
                                                trans_std=0.1,
                                                position_sensitive=True)
8116

8117
        # position_sensitive=False
8118
        import paddle.fluid as fluid
C
chengjuntao 已提交
8119
        input = fluid.data(name="input",
8120 8121
                           shape=[2, 192, 64, 64],
                           dtype='float32')
C
chengjuntao 已提交
8122 8123
        rois = fluid.data(name="rois",
                          shape=[-1, 4],
8124
                          dtype='float32',
C
chengjuntao 已提交
8125 8126
                          lod_level=1)
        trans = fluid.data(name="trans",
8127 8128 8129 8130 8131
                           shape=[2, 384, 64, 64],
                           dtype='float32')
        x = fluid.layers.deformable_roi_pooling(input=input,
                                                rois=rois,
                                                trans=trans,
C
chengjuntao 已提交
8132
                                                no_trans=False,
8133
                                                spatial_scale=1.0,
C
chengjuntao 已提交
8134 8135 8136 8137
                                                group_size=(1, 1),
                                                pooled_height=8,
                                                pooled_width=8,
                                                part_size=(8, 8),
8138
                                                sample_per_part=4,
C
chengjuntao 已提交
8139 8140
                                                trans_std=0.1,
                                                position_sensitive=False)
C
cjt222 已提交
8141 8142
    """

8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154
    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'
    )
8155
    if part_size is not None:
8156 8157 8158
        check_type(
            part_size, 'part_size', (list, tuple), 'deformable_roi_pooling'
        )
8159

C
cjt222 已提交
8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175
    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')
8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191
    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 已提交
8192
    return output
8193 8194


8195
@deprecated(since="2.0.0", update_to="paddle.shard_index")
8196 8197
def shard_index(input, index_num, nshards, shard_id, ignore_value=-1):
    """
L
lilong12 已提交
8198 8199 8200 8201 8202 8203 8204 8205 8206
    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).
8207 8208
    ::

8209
        shard_size = (index_num + nshards - 1) // nshards
8210

L
lilong12 已提交
8211 8212 8213
    For each value `v` in `input`, we reset it to a new value according to the
    following formula:
    ::
8214

L
lilong12 已提交
8215 8216 8217 8218
        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`.
8219 8220

    Args:
L
lilong12 已提交
8221 8222
        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`.
8223 8224 8225
        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.
8226 8227

    Returns:
L
lilong12 已提交
8228
        Tensor.
8229 8230 8231 8232

    Examples:
        .. code-block:: python

8233 8234 8235 8236 8237 8238 8239 8240
            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]]
8241
    """
H
hong 已提交
8242
    if in_dygraph_mode():
8243 8244 8245
        return _C_ops.shard_index(
            input, index_num, nshards, shard_id, ignore_value
        )
H
hong 已提交
8246

B
Baibaifan 已提交
8247
    check_variable_and_dtype(input, 'input', ['int64', 'int32'], 'shard_index')
8248 8249 8250
    op_type = 'shard_index'
    helper = LayerHelper(op_type, **locals())
    if shard_id < 0 or shard_id >= nshards:
8251 8252 8253
        raise ValueError(
            'The shard_id(%d) should be in [0, %d)' % (shard_id, nshards)
        )
8254 8255

    out = helper.create_variable_for_type_inference(dtype=input.dtype)
8256 8257 8258 8259 8260 8261 8262 8263 8264 8265 8266 8267
    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,
    )
8268
    return out
H
huangjun12 已提交
8269 8270 8271 8272


@templatedoc()
def hard_swish(x, threshold=6.0, scale=6.0, offset=3.0, name=None):
8273
    r"""
8274 8275 8276
    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 已提交
8277

8278
    The formula is as follows:
H
huangjun12 已提交
8279

8280
    .. math::
H
huangjun12 已提交
8281

8282
        out = \\frac{x * (min(max(0, x+offset), threshold))}{scale}
H
huangjun12 已提交
8283

8284 8285 8286 8287 8288 8289 8290 8291 8292
    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
8293 8294
        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`

8295 8296
    Returns:
        Variable: The output tensor with the same shape and data type as input.
8297 8298


8299
    Examples:
8300

8301
    .. code-block:: python
8302

8303
        import paddle.fluid as fluid
8304
        import paddle
8305
        import numpy as np
8306
        paddle.enable_static()
8307

8308
        DATATYPE='float32'
8309

8310
        x_data = np.array([i for i in range(1,5)]).reshape([1,1,4]).astype(DATATYPE)
8311

8312 8313
        x = fluid.data(name="x", shape=[None,1,4], dtype=DATATYPE)
        y = fluid.layers.hard_swish(x)
8314

8315 8316 8317 8318 8319
        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 已提交
8320
    """
J
Jiabin Yang 已提交
8321
    if _non_static_mode():
8322 8323 8324
        return _legacy_C_ops.hard_swish(
            x, 'threshold', threshold, 'scale', scale, 'offset', offset
        )
8325

8326 8327 8328
    check_variable_and_dtype(
        x, 'x', ['float16', 'float32', 'float64'], 'hard_swish'
    )
8329

H
huangjun12 已提交
8330 8331
    helper = LayerHelper('hard_swish', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
8332 8333 8334 8335 8336 8337
    helper.append_op(
        type='hard_swish',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'threshold': threshold, 'scale': scale, 'offset': offset},
    )
H
huangjun12 已提交
8338
    return out
R
ruri 已提交
8339 8340


K
Kaipeng Deng 已提交
8341 8342
@templatedoc()
def mish(x, threshold=20, name=None):
8343
    r"""
K
Kaipeng Deng 已提交
8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400
    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.]]
    """
8401
    if in_dygraph_mode():
8402
        return _C_ops.mish(x, threshold)
8403
    if _in_legacy_dygraph():
8404
        return _legacy_C_ops.mish(x, 'threshold', threshold)
8405

K
Kaipeng Deng 已提交
8406 8407
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'mish')
    check_type(threshold, 'threshold', (float, int), 'mish')
8408 8409 8410 8411 8412
    assert (
        threshold > 0
    ), "threshold of mish should be greater than 0, " "but got {}".format(
        threshold
    )
K
Kaipeng Deng 已提交
8413 8414 8415

    helper = LayerHelper('mish', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
8416 8417 8418 8419 8420 8421
    helper.append_op(
        type='mish',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'threshold': threshold},
    )
K
Kaipeng Deng 已提交
8422 8423 8424
    return out


G
Guo Sheng 已提交
8425
def gather_tree(ids, parents):
8426
    r"""
G
Guo Sheng 已提交
8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450
    To be used after beam search. After beam search, we get selected ids at
    each time step and the corresponding parents in the search tree. Both ids
    and parents have the layout :attr:`[max_time, batch_size, beam_size]`. Then
    :attr:`gather_tree` is used to backtrace from the last time step and
    generate the full sequences by collecting selected ids.

    Here is an example:

    .. code-block:: text

            Given:
                ids = [[[2 2]
                        [6 1]]
                       [[3 9]
                        [6 1]]
                       [[0 1]
                        [9 0]]]
                parents = [[[0 0]
                            [1 1]]
                           [[1 0]
                            [1 0]]
                           [[0 0]
                            [0 1]]]

8451 8452
            Then:
                gather_tree(ids, parents)
G
Guo Sheng 已提交
8453 8454 8455 8456 8457 8458 8459 8460
                         = [[[2 2]
                             [1 6]]
                            [[3 3]
                             [6 1]]
                            [[0 1]
                             [9 0]]]

    Args:
L
liu zhengxi 已提交
8461
        ids(Tensor): A Tensor with shape :attr:`[length, batch_size, beam_size]`
G
Guo Sheng 已提交
8462 8463
            and data type :attr:`int32` or :attr:`int64`. It contains the selected
            ids of all time steps.
L
liu zhengxi 已提交
8464
        parents(Tensor): A Tensor with the same shape and data type as :attr:`ids`,
G
Guo Sheng 已提交
8465 8466 8467 8468
            It contains the parents corresponding to selected ids when searching
            among beams.

    Returns:
L
liu zhengxi 已提交
8469
            A Tensor with the same shape and data type as :attr:`ids`. \
G
Guo Sheng 已提交
8470 8471 8472 8473 8474 8475
            It contains the full sequences. The sequences are collected from \
            :attr:`ids` by backtracing according to :attr:`parents`.

    Examples:
        .. code-block:: python

L
liu zhengxi 已提交
8476 8477 8478 8479 8480 8481 8482 8483
            import paddle

            ids = paddle.to_tensor([[[2, 2], [6, 1]], [[3, 9], [6, 1]], [[0, 1], [9, 0]]])

            parents = paddle.to_tensor([[[0, 0], [1, 1]], [[1, 0], [1, 0]], [[0, 0], [0, 1]]])

            final_sequences = paddle.nn.functional.gather_tree(ids, parents)
            # [[[2, 2], [1, 6]], [[3, 3], [6, 1]], [[0, 1], [9, 0]]]
G
Guo Sheng 已提交
8484 8485

    """
8486
    return paddle.nn.functional.gather_tree(ids, parents)
G
Guo Sheng 已提交
8487 8488


8489
@deprecated(since="2.0.0", update_to="paddle.uniform")
8490
@templatedoc()
8491 8492 8493
def uniform_random(
    shape, dtype='float32', min=-1.0, max=1.0, seed=0, name=None
):
8494
    """
8495 8496
    This OP returns a Tensor filled with random values sampled from a uniform
    distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.
8497 8498 8499

    Examples:
    ::
8500

8501 8502
        Input:
          shape = [1, 2]
8503

8504 8505 8506 8507
        Output:
          result=[[0.8505902, 0.8397286]]

    Args:
8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520
        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
8521 8522
            use a seed generated by the system. Note that if seed is not 0,
            this operator will always generate the same random numbers every
8523
            time. Default is 0.
8524 8525 8526
        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`.
8527

8528
    Returns:
8529 8530
        Tensor: A Tensor filled with random values sampled from a uniform
        distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.
8531

8532
    Raises:
8533 8534
        TypeError: If ``shape`` is not list, tuple, Tensor.
        TypeError: If ``dtype`` is not float32, float64.
8535

8536 8537 8538
    Examples:
        .. code-block:: python

8539
            import paddle
8540
            import paddle.fluid as fluid
8541
            paddle.enable_static()
8542 8543

            # example 1:
8544
            # attr shape is a list which doesn't contain Tensor.
8545
            result_1 = fluid.layers.uniform_random(shape=[3, 4])
8546 8547 8548
            # [[ 0.84524226,  0.6921872,   0.56528175,  0.71690357],
            #  [-0.34646994, -0.45116323, -0.09902662, -0.11397249],
            #  [ 0.433519,    0.39483607, -0.8660099,   0.83664286]]
8549 8550

            # example 2:
8551 8552 8553
            # 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)
8554
            result_2 = fluid.layers.uniform_random(shape=[dim_1, dim_2])
8555 8556
            # [[-0.9951253,   0.30757582, 0.9899647 ],
            #  [ 0.5864527,   0.6607096,  -0.8886161 ]]
8557 8558

            # example 3:
8559
            # attr shape is a Tensor, the data type must be int64 or int32.
8560
            var_shape = fluid.data(name='var_shape', shape=[2], dtype="int64")
8561
            result_3 = fluid.layers.uniform_random(var_shape)
8562 8563 8564 8565
            # if var_shape's value is [2, 3]
            # result_3 is:
            # [[-0.8517412,  -0.4006908,   0.2551912 ],
            #  [ 0.3364414,   0.36278176, -0.16085452]]
8566

8567 8568 8569
    """
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
8570

8571 8572
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
8573
        return _C_ops.uniform(
8574 8575 8576 8577 8578 8579 8580
            shape,
            dtype,
            float(min),
            float(max),
            seed,
            _current_expected_place(),
        )
8581
    elif _in_legacy_dygraph():
8582
        shape = utils.convert_shape_to_list(shape)
8583 8584 8585 8586 8587 8588 8589 8590 8591 8592 8593 8594
        return _legacy_C_ops.uniform_random(
            'shape',
            shape,
            'min',
            float(min),
            'max',
            float(max),
            'seed',
            seed,
            'dtype',
            dtype,
        )
8595

8596
    check_type(shape, 'shape', (list, tuple, Variable), 'uniform_random/rand')
8597 8598 8599
    check_dtype(
        dtype, 'dtype', ('float32', 'float64', 'uint16'), 'uniform_random/rand'
    )
8600 8601
    check_type(min, 'min', (float, int, Variable), 'uniform_random/rand')
    check_type(max, 'max', (float, int, Variable), 'uniform_random/rand')
8602 8603

    inputs = dict()
8604
    attrs = {'seed': seed, 'min': min, 'max': max, 'dtype': dtype}
8605 8606 8607
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='uniform_random/rand'
    )
8608

8609
    helper = LayerHelper("uniform_random", **locals())
8610
    out = helper.create_variable_for_type_inference(dtype)
8611 8612 8613
    helper.append_op(
        type="uniform_random", inputs=inputs, attrs=attrs, outputs={"Out": out}
    )
8614
    utils.try_set_static_shape_tensor(out, shape)
8615
    return out
myq406450149's avatar
myq406450149 已提交
8616 8617 8618 8619 8620 8621 8622


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

myq406450149's avatar
myq406450149 已提交
8624 8625 8626 8627 8628 8629 8630 8631 8632 8633 8634 8635 8636 8637 8638 8639 8640 8641 8642 8643 8644 8645 8646 8647 8648
        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()
8649 8650 8651
    check_dtype(
        dtype, 'unbind', ['float32', 'float64', 'int32', 'int64'], 'unbind'
    )
myq406450149's avatar
myq406450149 已提交
8652
    if not isinstance(axis, (int)):
8653 8654 8655
        raise TypeError(
            "The type of 'axis'  must be int, but received %s." % (type(axis))
        )
myq406450149's avatar
myq406450149 已提交
8656 8657 8658 8659 8660 8661 8662 8663 8664 8665
    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)
    ]

8666 8667 8668 8669 8670 8671
    helper.append_op(
        type="unbind",
        inputs={"X": input},
        outputs={"Out": outs},
        attrs={"axis": axis},
    )
myq406450149's avatar
myq406450149 已提交
8672
    return outs