nn.py 315.4 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 95 96 97
    'smooth_l1',
    'one_hot',
    'autoincreased_step_counter',
    'unsqueeze',
    'lod_reset',
    'pad',
    'image_resize',
    'resize_bilinear',
K
Kaipeng Deng 已提交
98
    'resize_trilinear',
99
    'resize_nearest',
X
Xin Pan 已提交
100 101 102
    'relu',
    'log',
    'prelu',
Z
zhoukunsheng 已提交
103
    'unique',
104
    'unique_with_counts',
X
Xin Pan 已提交
105 106 107 108 109 110 111 112 113 114 115 116
    'elementwise_add',
    'elementwise_div',
    'elementwise_sub',
    'elementwise_mul',
    'gaussian_random',
    'sampling_id',
    'sum',
    'shape',
    'clip',
    'clip_by_norm',
    'mean',
    'mul',
M
minqiyang 已提交
117
    'hash',
D
dengkaipeng 已提交
118
    'grid_sampler',
G
gmcather 已提交
119
    'log_loss',
Q
Qiao Longfei 已提交
120
    'bilinear_tensor_product',
C
chengduo 已提交
121 122
    'merge_selected_rows',
    'get_tensor_from_selected_rows',
123
    'temporal_shift',
S
sneaxiy 已提交
124
    'py_func',
R
ruri 已提交
125
    'pixel_shuffle',
126
    'fsp_matrix',
H
heqiaozhi 已提交
127
    'continuous_value_model',
Z
zhoukunsheng 已提交
128
    'where',
Z
zhoukunsheng 已提交
129
    'sign',
130
    'unfold',
C
cjt222 已提交
131
    'deformable_roi_pooling',
132
    'shard_index',
H
huangjun12 已提交
133
    'hard_swish',
K
Kaipeng Deng 已提交
134
    'mish',
G
Guo Sheng 已提交
135
    'gather_tree',
136
    'uniform_random',
myq406450149's avatar
myq406450149 已提交
137
    'unbind',
Y
Yu Yang 已提交
138 139
]

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

Y
Yu Yang 已提交
152

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

    return reduce_all, dim


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

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

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

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

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

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

232 233 234 235
    .. math::

        Out = Act({XW + b})

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

    .. math::

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

    In the above equation:

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

    .. code-block:: text

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

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

    Examples:
        .. code-block:: python

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

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

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

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


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

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

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

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

420
        Case 2:
421

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

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

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

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

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

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

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

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

    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

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


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


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


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


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


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

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

    ${comment}

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

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

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

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

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

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

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

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

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

    return log_likelihood


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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

    Examples:
        .. code-block:: python

N
Noel 已提交
1026 1027 1028 1029 1030 1031 1032
            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 已提交
1033
    """
1034 1035
    check_variable_and_dtype(X, 'X', ['float32'], 'cos_sim')
    check_variable_and_dtype(Y, 'Y', ['float32'], 'cos_sim')
F
fengjiayi 已提交
1036
    helper = LayerHelper('cos_sim', **locals())
X
Xin Pan 已提交
1037 1038 1039
    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)
1040 1041 1042 1043 1044
    helper.append_op(
        type='cos_sim',
        inputs={'X': [X], 'Y': [Y]},
        outputs={'Out': [out], 'XNorm': [xnorm], 'YNorm': [ynorm]},
    )
Y
Yu Yang 已提交
1045 1046 1047
    return out


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

1059 1060 1061 1062
    Computes dropout.

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

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

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

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

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

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

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

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

M
minqiyang 已提交
1097

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

    Examples:
1102

1103 1104
        .. code-block:: python

1105
            import paddle
1106
            import paddle.fluid as fluid
1107

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

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

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

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

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

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


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

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

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

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

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

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

1207
    .. math::
1208

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

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

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

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

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

    Examples:

        .. code-block:: python

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

    """
1294

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

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

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

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

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


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

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

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

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

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

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

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

    Example:

1372 1373
        - Input:

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

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

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

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

C
chengduoZH 已提交
1382
        Where
1383 1384

        .. math::
C
chengduoZH 已提交
1385

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

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

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

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

1464 1465
          import paddle
          paddle.enable_static()
1466

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return helper.append_activation(pre_act)


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

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

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

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

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

    Examples:

        .. code-block:: python

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

          paddle.enable_static()
1731

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

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

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

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

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

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

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

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

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

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

    return pool_out


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

1914
    ${comment}
1915 1916

    Args:
K
Kaipeng Deng 已提交
1917 1918
        input (Variable): The input tensor of pooling operator, which is a 5-D tensor with
                          shape [N, C, D, H, W]. The format of
1919 1920 1921
                          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 已提交
1922
                          of the feature.
1923 1924
        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 已提交
1925 1926 1927
            (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}
1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938
        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]]`.
1939 1940 1941
        global_pooling (bool): ${global_pooling_comment}
        use_cudnn (bool): ${use_cudnn_comment}
        ceil_mode (bool): ${ceil_mode_comment}
K
Kaipeng Deng 已提交
1942 1943 1944
        name(str, optional): For detailed information, please refer
                             to :ref:`api_guide_Name`. Usually name is no need to set and
                             None by default.
1945
        exclusive (bool): Whether to exclude padding points in average pooling
1946 1947 1948 1949
                          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]`.
1950

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

1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966
    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 已提交
1967 1968 1969 1970
    Examples:

        .. code-block:: python

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

          paddle.enable_static()
1975

K
Kaipeng Deng 已提交
1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000
          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)
2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023

          # 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 已提交
2024 2025 2026
    """
    if pool_type not in ["max", "avg"]:
        raise ValueError(
2027
            "Unknown Attr(pool_type): '%s'. It can only be 'max' or 'avg'.",
2028 2029
            str(pool_type),
        )
C
chengduoZH 已提交
2030

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

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

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

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

2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063
    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 "
2064 2065
                        "is not supported." % str(padding)
                    )
2066 2067 2068 2069 2070 2071
                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 "
2072 2073
                        "is not supported." % str(padding)
                    )
2074 2075 2076
                padding = padding[1:4]
                padding = [ele for a_list in padding for ele in a_list]
            padding = utils.convert_to_list(padding, 6, 'padding')
2077 2078
            if utils._is_symmetric_padding(padding, 3):
                padding = [padding[0], padding[2], padding[4]]
2079 2080 2081

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

    pool_padding = update_padding(pool_padding, data_format)

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

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

    return pool_out


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

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

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

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

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

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

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

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

2185

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

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

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

    Examples:

        .. code-block:: python

2257
            import paddle
2258

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

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

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

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

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

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

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

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

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

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

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

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

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

    return helper.append_activation(batch_norm_out)


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

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

    The formula is as follows:

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

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

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

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

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

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

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

    Examples:

2526 2527
        .. code-block:: python

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

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

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

    return helper.append_activation(layer_norm_out)


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

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

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

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

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

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

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

    .. math::

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

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

2633

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

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

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

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

2652
            import paddle
K
Kaipeng Deng 已提交
2653

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

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

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

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

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

2717
    return out
D
Dun 已提交
2718 2719


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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

G
guosheng 已提交
2833 2834 2835
            # 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 已提交
2836
            # Each example is followed by the corresponding output tensor.
2837
            x = fluid.data(name='x', shape=[2, 4], dtype='float32')
G
guosheng 已提交
2838 2839 2840
            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]
2841
            fluid.layers.reduce_mean(x, dim=1, keep_dim=True)  # [[0.475], [0.4]]
W
whs 已提交
2842

2843
            # y is a Tensor variable with shape [2, 2, 2] and elements as below:
W
whs 已提交
2844 2845
            #      [[[1.0, 2.0], [3.0, 4.0]],
            #      [[5.0, 6.0], [7.0, 8.0]]]
T
tianshuo78520a 已提交
2846
            # Each example is followed by the corresponding output tensor.
2847
            y = fluid.data(name='y', shape=[2, 2, 2], dtype='float32')
2848 2849
            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 已提交
2850
    """
2851

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


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

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

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

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

    Examples:
        .. code-block:: python
2878

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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


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

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

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

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

3009 3010
            import paddle.fluid as fluid

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

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

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

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

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

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

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

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

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

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

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

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


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

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

3169
    .. math::
3170 3171

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

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

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

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

    Examples:
3189

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

3193
        import paddle
3194

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

3397 3398 3399 3400 3401
        Case 1:

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

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

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

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

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

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

    Examples:
        .. code-block:: python

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

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

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

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


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

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

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

3495 3496 3497 3498 3499
    A simple example as below:

    .. code-block:: text

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

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

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

W
whs 已提交
3514
        Computation:
3515

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

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

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

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

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

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

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

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

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

3592 3593 3594 3595

    Examples:
        .. code-block:: python

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

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

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

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

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

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

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


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

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

    .. math::

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

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

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

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

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

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

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

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

    Return Type: Variable
3705 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

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

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

3747
            output.dims = {8, 8}
3748

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

T
Tink_Y 已提交
3751
    Examples:
3752 3753 3754

        .. code-block:: python

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

3763 3764

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

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

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


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

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

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

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

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

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


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

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

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

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

3853
    For Example:
L
lujun 已提交
3854

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

3857
                Given:
L
lujun 已提交
3858

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

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

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


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

    Examples:
3882

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

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

3894
    """
3895 3896

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

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

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


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

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

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

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

    Examples:
        .. code-block:: python

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

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

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

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

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


4002
@deprecated(since='2.0.0', update_to='paddle.nn.functional.one_hot')
4003
def one_hot(input, depth, allow_out_of_range=False):
4004
    """
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

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

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

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

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

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

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

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

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


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

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

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

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

    Examples:
        .. code-block:: python

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

    return counter
Y
yangyaming 已提交
4167 4168


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

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

    .. code-block:: text

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

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

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

    Examples:
        .. code-block:: python

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

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

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

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

4255 4256
    return out

4257

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

    .. code-block:: text

        * Example 1:

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

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

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

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

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

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

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

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

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

    Examples:
        .. code-block:: python

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


4362
def pad(x, paddings, pad_value=0.0, name=None):
4363
    r"""
4364
    :alias_main: paddle.nn.functional.pad
4365 4366
        :alias: paddle.nn.functional.pad,paddle.nn.functional.common.pad
        :old_api: paddle.fluid.layers.pad
4367

S
SunGaofeng 已提交
4368 4369
    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 已提交
4370

S
SunGaofeng 已提交
4371 4372 4373 4374
    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 已提交
4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392

    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 已提交
4393
        x (Variable): Tensor, data type is float32.
G
guosheng 已提交
4394
        paddings (list): A list of integers. Its elements specify the padded
S
SunGaofeng 已提交
4395
                         width before and after each dimension in turn.
4396
                         The length of :attr:`paddings` must be equal to
G
guosheng 已提交
4397 4398
                         :math:`rank(x) \\times 2`.
        pad_value (float): The constant value used to pad.
4399 4400
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
4401
                             For more information, please refer to :ref:`api_guide_Name`
G
guosheng 已提交
4402 4403

    Returns:
S
SunGaofeng 已提交
4404 4405 4406 4407
        The padded tensor, with the same data type and rank as :attr:`x`

    Return Type:
        Variable
G
guosheng 已提交
4408 4409 4410

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

4412
            # x is a rank 2 tensor variable
S
SunGaofeng 已提交
4413
            import paddle.fluid as fluid
4414 4415
            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 已提交
4416
    """
4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430
    check_variable_and_dtype(
        x,
        'x',
        [
            'float16',
            'float32',
            'float64',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        "pad",
    )
4431

4432 4433 4434 4435
    check_type(pad_value, 'pad_value', (float, int, Variable), 'pad')
    if isinstance(pad_value, int):
        pad_value = float(pad_value)

4436 4437
    helper = LayerHelper('pad', **locals())
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
4438
    out = helper.create_variable_for_type_inference(dtype)
4439 4440 4441 4442 4443 4444
    helper.append_op(
        type='pad',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'paddings': paddings, 'pad_value': pad_value},
    )
G
guosheng 已提交
4445
    return out
4446 4447


4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458
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',
):
4459
    """
4460

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

4463 4464
    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)
4465 4466
    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 已提交
4467
    and the resizing only applies on the three dimensions(depth, height and width).
4468

4469
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in the
4470 4471
    future and only use :attr:`out_shape` instead.

4472
    Supporting resample methods:
4473
        'LINEAR' : Linear interpolation
Q
update  
qiaolongfei 已提交
4474

4475
        'BILINEAR' : Bilinear interpolation
T
Tink_Y 已提交
4476

K
Kaipeng Deng 已提交
4477 4478
        'TRILINEAR' : Trilinear interpolation

4479
        'NEAREST' : Nearest neighbor interpolation
4480

4481
        'BICUBIC' : Bicubic interpolation
4482 4483

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

4486
    Nearest neighbor interpolation is to perform nearest neighbor interpolation
4487
    in both the 3rd dimension(in height direction) and the 4th dimension(in width
4488
    direction) on input tensor.
4489 4490 4491 4492 4493

    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
4494 4495
    again in the other direction.

4496 4497 4498
    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 已提交
4499
    The linear interpolation is performed on three directions.
4500

4501 4502 4503 4504
    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 已提交
4505

4506
    Align_corners and align_mode are optional parameters,the calculation method
4507 4508 4509 4510
    of interpolation can be selected by them.

    Example:

T
Tink_Y 已提交
4511
    .. code-block:: text
4512

T
Tink_Y 已提交
4513
        For scale:
4514

T
Tink_Y 已提交
4515
            if align_corners = True && out_size > 1 :
4516

T
Tink_Y 已提交
4517
              scale_factor = (in_size-1.0)/(out_size-1.0)
4518

T
Tink_Y 已提交
4519
            else:
4520

T
Tink_Y 已提交
4521
              scale_factor = float(in_size/out_size)
4522 4523


T
Tink_Y 已提交
4524
        Nearest neighbor interpolation:
4525

T
Tink_Y 已提交
4526 4527
          if:
              align_corners = False
4528

T
Tink_Y 已提交
4529 4530
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4531

T
Tink_Y 已提交
4532 4533
              H_out = floor (H_{in} * scale_{factor})
              W_out = floor (W_{in} * scale_{factor})
4534

T
Tink_Y 已提交
4535 4536
          else:
              align_corners = True
4537

T
Tink_Y 已提交
4538 4539
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4540

T
Tink_Y 已提交
4541 4542
              H_out = round(H_{in} * scale_{factor})
              W_out = round(W_{in} * scale_{factor})
4543

4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560
        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 已提交
4561 4562 4563 4564
        Bilinear interpolation:

          if:
              align_corners = False , align_mode = 0
4565

T
Tink_Y 已提交
4566 4567
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4568

T
Tink_Y 已提交
4569 4570
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5
4571

T
Tink_Y 已提交
4572
          else:
4573

T
Tink_Y 已提交
4574 4575
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
4576

T
Tink_Y 已提交
4577 4578
              H_out = H_{in} * scale_{factor}
              W_out = W_{in} * scale_{factor}
4579

K
Kaipeng Deng 已提交
4580 4581 4582 4583
        Trilinear interpolation:

          if:
              align_corners = False , align_mode = 0
4584

K
Kaipeng Deng 已提交
4585 4586
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:
4587

K
Kaipeng Deng 已提交
4588 4589 4590 4591 4592 4593
              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:
4594

K
Kaipeng Deng 已提交
4595 4596 4597 4598
              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}
4599

4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611
        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 已提交
4612 4613
              H_out = H_{in} * scale_{factor}
              W_out = W_{in} * scale_{factor}
4614

4615

4616 4617
    For details of linear interpolation, please refer to Wikipedia:
    https://en.wikipedia.org/wiki/Linear_interpolation.
4618

4619
    For details of nearest neighbor interpolation, please refer to Wikipedia:
4620
    https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation.
4621

4622
    For details of bilinear interpolation, please refer to Wikipedia:
4623
    https://en.wikipedia.org/wiki/Bilinear_interpolation.
4624

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

4628 4629
    For details of bicubic interpolation, please refer to Wikipedia:
    https://en.wikipedia.org/wiki/Bicubic_interpolation
4630

R
ruri 已提交
4631
    Parameters:
4632
        input (Variable): 3-D, 4-D or 5-D Tensor, its data type is float32, float64, or uint8,
4633
                          its data format is specified by :attr:`data_format`.
4634
        out_shape (list|tuple|Variable|None): Output shape of image resize
4635 4636
             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.
4637
             Default: None. If a list, each element can be an integer or a Tensor Variable of shape: [1].
4638
             If a Tensor Variable, its dimensions size should be a 1.
4639 4640 4641
        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 已提交
4642
             Default: None.
4643 4644
        name(str|None): A name for this layer(optional). If set None, the layer
                        will be named automatically.
4645
        resample(str): The resample method. It supports 'LINEAR', 'BICUBIC', 'BILINEAR', 'TRILINEAR'
K
Kaipeng Deng 已提交
4646
                       and 'NEAREST' currently. Default: 'BILINEAR'
4647 4648 4649
        actual_shape(Variable): An optional input to specify output shape
                                dynamically. If provided, image resize
                                according to this given shape rather than
4650
                                :attr:`out_shape` and :attr:`scale` specifying
4651 4652
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
4653 4654 4655 4656 4657
                                :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 已提交
4658
                                errors would be occurred in graph constructing stage.
4659
                                Default: None
4660 4661
        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
4662 4663
                               corner pixels.
                               Default: True
4664 4665
        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 ,
4666
                            can be \'1\' for src_idx = scale*dst_index.
4667
        data_format (str, optional): Specify the data format of the input, and the data format of the output
4668
            will be consistent with that of the input. An optional string from:`NCW`, `NWC`, `"NCHW"`, `"NHWC"`, `"NCDHW"`,
4669
            `"NDHWC"`. The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
4670
            `[batch_size, input_channels, input_height, input_width]`. When it is `"NCHW"`, the data is stored
4671
            in the order of: `[batch_size, input_channels, input_depth, input_height, input_width]`.
4672 4673

    Returns:
4674
        A 3-D Tensor of the shape (num_batches, channels, out_w) or (num_batches, out_w, channels),
4675 4676
        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 已提交
4677

4678 4679 4680
    Raises:
        TypeError: out_shape should be a list or tuple or Variable.
        TypeError: actual_shape should either be Variable or None.
4681 4682
        ValueError: The 'resample' of image_resize can only be 'LINEAR', 'BILINEAR',
                    'TRILINEAR', 'BICUBIC' or 'NEAREST' currently.
4683
        ValueError: 'LINEAR' only support 3-D tensor.
4684
        ValueError: 'BICUBIC', 'BILINEAR' and 'NEAREST' only support 4-D tensor.
K
Kaipeng Deng 已提交
4685
        ValueError: 'TRILINEAR' only support 5-D tensor.
4686
        ValueError: One of out_shape and scale must not be None.
4687
        ValueError: out_shape length should be 1 for input 3-D tensor.
K
Kaipeng Deng 已提交
4688 4689
        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 已提交
4690
        ValueError: scale should be greater than zero.
T
tianshuo78520a 已提交
4691
        TypeError: align_corners should be a bool value
4692
        ValueError: align_mode can only be '0' or '1'
4693
        ValueError: data_format can only be 'NCW', 'NWC', 'NCHW', 'NHWC', 'NCDHW' or 'NDHWC'.
4694

4695 4696
    Examples:
        .. code-block:: python
4697

4698 4699 4700 4701 4702 4703
            #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 已提交
4704

4705 4706
            #1
            output = fluid.layers.image_resize(input=input,out_shape=[12,12])
R
ruri 已提交
4707

4708 4709 4710 4711 4712
            #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 已提交
4713

4714 4715 4716 4717 4718
            #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 已提交
4719

4720 4721 4722 4723 4724
            #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 已提交
4725

4726 4727 4728
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
4729

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

4732
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
4733 4734 4735
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
4736

4737
            print(output_data[0].shape)
4738

4739 4740 4741 4742 4743 4744 4745 4746
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
4747

4748 4749
            #imperative mode
            import paddle.fluid.dygraph as dg
4750

4751 4752 4753 4754
            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)
4755

4756
                # [2L, 3L, 12L, 12L]
4757

4758
    """
4759
    resample_methods = {
4760
        'LINEAR': 'linear',
4761
        'BILINEAR': 'bilinear',
K
Kaipeng Deng 已提交
4762
        'TRILINEAR': 'trilinear',
4763
        'NEAREST': 'nearest',
4764
        'LINEAR': 'linear',
4765
    }
4766
    resample = resample.upper()
4767 4768
    if resample not in resample_methods:
        raise ValueError(
4769
            "The 'resample' of image_resize can only be 'LINEAR', 'BILINEAR', 'TRILINEAR' "
4770 4771
            "or 'NEAREST' currently."
        )
4772
    resample_type = resample_methods[resample]
4773

4774 4775 4776
    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 已提交
4777
        raise ValueError("'BILINEAR' and 'NEAREST' only support 4-D tensor.")
4778
    elif resample == 'TRILINEAR' and len(input.shape) != 5:
K
Kaipeng Deng 已提交
4779 4780
        raise ValueError("'TRILINEAR'only support 5-D tensor.")

4781 4782 4783 4784 4785
    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")

4786
    if out_shape is None and scale is None:
4787
        raise ValueError("One of out_shape and scale must not be None.")
4788
    helper = LayerHelper('{}_interp'.format(resample_type), **locals())
4789
    dtype = helper.input_dtype()
4790

4791
    if len(input.shape) == 3 and data_format not in ['NCW', 'NWC']:
4792
        raise ValueError(
4793 4794 4795 4796
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCW` or `NWC` supported for 3-D input."
        )
4797
    elif len(input.shape) == 4 and data_format not in ['NCHW', 'NHWC']:
4798
        raise ValueError(
4799 4800 4801 4802
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCHW` or `NHWC` supported for 4-D input."
        )
4803 4804
    elif len(input.shape) == 5 and data_format not in ['NCDHW', 'NDHWC']:
        raise ValueError(
4805 4806 4807 4808
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCDHW` or `NDHWC` supported for 5-D input."
        )
4809

4810
    def _is_list_or_turple_(data):
4811
        return isinstance(data, list) or isinstance(data, tuple)
4812

4813
    if data_format == 'NCHW' or data_format == 'NCDHW' or data_format == 'NCW':
4814
        data_layout = 'NCHW'
4815
    if data_format == 'NHWC' or data_format == 'NDHWC' or data_format == 'NWC':
4816 4817
        data_layout = 'NHWC'

4818
    inputs = {"X": input}
D
dengkaipeng 已提交
4819
    attrs = {
4820 4821 4822
        "out_d": -1,
        "out_h": -1,
        "out_w": -1,
D
dengkaipeng 已提交
4823 4824
        "interp_method": resample_type,
        "align_corners": align_corners,
4825
        "align_mode": align_mode,
4826
        "data_layout": data_layout,
D
dengkaipeng 已提交
4827 4828
    }

4829
    if out_shape is not None:
4830
        if isinstance(out_shape, Variable) and not _non_static_mode():
4831
            out_shape.stop_gradient = True
4832
            inputs['OutSize'] = out_shape
4833
        else:
4834 4835 4836 4837 4838 4839 4840 4841
            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]
4842
            if not (_is_list_or_turple_(out_shape)):
D
dengkaipeng 已提交
4843
                raise TypeError(
4844 4845
                    "out_shape should be a list or tuple or Variable."
                )
4846 4847 4848 4849 4850 4851
            # Validate the shape
            contain_var = False
            for dim_idx, dim_size in enumerate(out_shape):
                if isinstance(dim_size, Variable):
                    contain_var = True
                    continue
4852 4853 4854
                assert (
                    dim_size > 0
                ), "Each dimension size given in out_shape must be greater than 0."
4855 4856 4857 4858 4859 4860 4861 4862 4863 4864

            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:
4865
                        assert isinstance(dim, int)
4866
                        temp_out = helper.create_variable_for_type_inference(
4867 4868 4869 4870 4871
                            'int32'
                        )
                        fill_constant(
                            [1], 'int32', dim, force_cpu=True, out=temp_out
                        )
4872 4873 4874 4875
                        new_size_tensor.append(temp_out)
                        size_list.append(dim)
                inputs['SizeTensor'] = new_size_tensor

4876 4877
            if len(input.shape) == 3:
                if len(out_shape) != 1:
4878 4879 4880
                    raise ValueError(
                        "out_shape length should be 1 for " "input 3-D tensor."
                    )
4881 4882 4883 4884 4885 4886
                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 已提交
4887
                if len(out_shape) != 2:
4888 4889 4890
                    raise ValueError(
                        "out_shape length should be 2 for " "input 4-D tensor."
                    )
4891 4892 4893 4894 4895 4896 4897
                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 已提交
4898 4899
            if len(input.shape) == 5:
                if len(out_shape) != 3:
4900 4901 4902
                    raise ValueError(
                        "out_shape length should be 3 for " "input 5-D tensor."
                    )
4903 4904 4905 4906 4907 4908 4909 4910 4911
                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]
4912

4913
    else:
4914 4915 4916
        if _non_static_mode() and isinstance(scale, Variable):
            scale = scale.numpy()
        elif isinstance(scale, Variable):
4917 4918
            scale.stop_gradient = True
            inputs["Scale"] = scale
4919
        elif isinstance(scale, float) or isinstance(scale, int):
4920
            if scale <= 0:
4921
                raise ValueError("Attr(scale) should be greater than zero.")
4922
            attrs['scale'] = float(scale)
4923 4924
        else:
            raise TypeError(
4925 4926
                "Attr(scale)'s type should be float, int or Variable."
            )
4927

4928
    if isinstance(actual_shape, Variable):
4929 4930 4931 4932 4933
        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
4934 4935 4936
        inputs["OutSize"] = actual_shape
    elif actual_shape is not None:
        raise TypeError("actual_shape should either be Variable or None.")
4937 4938 4939 4940 4941 4942 4943 4944 4945

    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":
4946
            out = _legacy_C_ops.linear_interp(input, actual_shape, *dy_attr)
4947
        elif resample_type == "bilinear":
4948
            out = _legacy_C_ops.bilinear_interp(input, actual_shape, *dy_attr)
4949
        elif resample_type == "trilinear":
4950
            out = _legacy_C_ops.trilinear_interp(input, actual_shape, *dy_attr)
4951
        elif resample_type == "nearest":
4952
            out = _legacy_C_ops.nearest_interp(input, actual_shape, *dy_attr)
4953
        elif resample_type == "bicubic":
4954
            out = _legacy_C_ops.bicubic_interp(input, actual_shape, *dy_attr)
4955 4956
        return out

X
Xin Pan 已提交
4957
    out = helper.create_variable_for_type_inference(dtype)
4958 4959 4960 4961 4962 4963
    helper.append_op(
        type='{}_interp'.format(resample_type),
        inputs=inputs,
        outputs={"Out": out},
        attrs=attrs,
    )
4964
    return out
F
stash  
fengjiayi 已提交
4965 4966


4967
@templatedoc(op_type="bilinear_interp")
4968 4969 4970 4971 4972 4973 4974 4975 4976 4977
def resize_bilinear(
    input,
    out_shape=None,
    scale=None,
    name=None,
    actual_shape=None,
    align_corners=True,
    align_mode=1,
    data_format='NCHW',
):
4978
    """
4979

R
ruri 已提交
4980
    This op resizes the input by performing bilinear interpolation based on given
4981
    output shape which specified by actual_shape, out_shape and scale
4982 4983
    in priority order.

4984
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in
4985 4986
    the future and only use :attr:`out_shape` instead.

4987 4988 4989 4990
    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
4991 4992
    again in the other direction.

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

4996
    Align_corners and align_mode are optional parameters,the calculation
4997 4998 4999 5000
    method of interpolation can be selected by them.

    Example:

T
Tink_Y 已提交
5001
    .. code-block:: text
5002

T
Tink_Y 已提交
5003
        For scale:
5004

T
Tink_Y 已提交
5005
            if align_corners = True && out_size > 1 :
5006

T
Tink_Y 已提交
5007
              scale_factor = (in_size-1.0)/(out_size-1.0)
5008

T
Tink_Y 已提交
5009
            else:
5010

5011
              scale_factor = float(in_size/out_size)
5012

T
Tink_Y 已提交
5013 5014 5015 5016
        Bilinear interpolation:

          if:
              align_corners = False , align_mode = 0
5017

T
Tink_Y 已提交
5018 5019
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5020

T
Tink_Y 已提交
5021 5022
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5
5023

T
Tink_Y 已提交
5024
          else:
T
tink2123 已提交
5025

T
Tink_Y 已提交
5026 5027 5028 5029
              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}
5030

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

    Returns:
5064
        Variable: 4-D tensor(NCHW or NHWC).
5065

5066 5067
    Examples:
        .. code-block:: python
5068

5069 5070 5071 5072 5073 5074
            #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 已提交
5075

5076 5077
            #1
            output = fluid.layers.resize_bilinear(input=input,out_shape=[12,12])
R
ruri 已提交
5078

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

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

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

5097 5098 5099
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5100

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

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

5108
            print(output_data[0].shape)
5109

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

5119 5120
            #imperative mode
            import paddle.fluid.dygraph as dg
5121

5122 5123 5124 5125
            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)
5126

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

5129 5130
    """

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


K
Kaipeng Deng 已提交
5144
@templatedoc(op_type="trilinear_interp")
5145 5146 5147 5148 5149 5150 5151 5152 5153 5154
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 已提交
5155
    """
5156

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

5161
    **Warning:** the parameter :attr:`actual_shape` will be deprecated
5162 5163
    in the future and only use :attr:`out_shape` instead.

5164 5165 5166
    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 已提交
5167 5168 5169 5170 5171
    The linear interpolation is performed on three directions.

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

5172
    Align_corners and align_mode are optional parameters,the calculation
K
Kaipeng Deng 已提交
5173 5174 5175 5176 5177 5178 5179
    method of interpolation can be selected by them.

    Example:

    .. code-block:: text

        For scale:
5180

K
Kaipeng Deng 已提交
5181 5182 5183
            if align_corners = True && out_size > 1 :

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

K
Kaipeng Deng 已提交
5185
            else:
5186 5187

              scale_factor = float(in_size/out_size)
K
Kaipeng Deng 已提交
5188 5189 5190 5191

        Bilinear interpolation:

          if:
5192

K
Kaipeng Deng 已提交
5193
              align_corners = False , align_mode = 0
5194

K
Kaipeng Deng 已提交
5195 5196
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:
5197

K
Kaipeng Deng 已提交
5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210
              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 已提交
5211
    Parameters:
5212 5213
        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 已提交
5214
        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.
5215
        scale(float|Variable|None): The multiplier for the input depth, height or width.
5216 5217
             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 已提交
5218
             Default: None.
R
ruri 已提交
5219
        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 已提交
5220 5221 5222 5223 5224 5225
        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
5226 5227 5228 5229 5230
                                :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 已提交
5231
                                errors would be occurred in graph constructing stage.
K
Kaipeng Deng 已提交
5232 5233 5234
                                Default: None
        align_corners(bool): ${align_corners_comment}
        align_mode(bool): ${align_mode_comment}
5235
        data_format (str, optional): Specify the data format of the input, and the data format of the output
5236 5237 5238
            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 已提交
5239 5240

    Returns:
5241
        Variable: A 5-D Tensor(NCDHW or NDHWC)
K
Kaipeng Deng 已提交
5242 5243 5244

    Examples:
        .. code-block:: python
5245

5246 5247 5248 5249 5250 5251
            #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 已提交
5252

5253 5254
            #1
            output = fluid.layers.resize_trilinear(input=input,out_shape=[12,12,12])
R
ruri 已提交
5255

5256 5257 5258 5259 5260
            #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 已提交
5261

5262 5263 5264 5265 5266
            #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 已提交
5267

5268 5269 5270 5271 5272
            #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 已提交
5273

5274 5275 5276
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5277

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

5280
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
5281 5282 5283
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
5284

5285
            print(output_data[0].shape)
R
ruri 已提交
5286

5287 5288 5289 5290 5291 5292 5293 5294
            #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 已提交
5295

5296 5297
            #imperative mode
            import paddle.fluid.dygraph as dg
5298

5299 5300 5301 5302
            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)
5303

5304
                # [2L, 3L, 12L, 12L, 12L]
5305 5306 5307



K
Kaipeng Deng 已提交
5308 5309
    """

5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'TRILINEAR',
        actual_shape,
        align_corners,
        align_mode,
        data_format,
    )
K
Kaipeng Deng 已提交
5321 5322


5323
@templatedoc(op_type="nearest_interp")
5324 5325 5326 5327 5328 5329 5330 5331 5332
def resize_nearest(
    input,
    out_shape=None,
    scale=None,
    name=None,
    actual_shape=None,
    align_corners=True,
    data_format='NCHW',
):
5333
    """
5334

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

5339
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in the
5340 5341
    future and only use :attr:`out_shape` instead.

5342 5343
    Example:

T
Tink_Y 已提交
5344 5345 5346
    .. code-block:: text

        For scale:
5347

T
Tink_Y 已提交
5348 5349
            if align_corners = True && out_size > 1 :
              scale_factor = (in_size-1.0)/(out_size-1.0)
5350

T
Tink_Y 已提交
5351
            else:
5352

T
Tink_Y 已提交
5353
              scale_factor = float(in_size/out_size)
5354

T
Tink_Y 已提交
5355
        Nearest neighbor interpolation:
5356

T
Tink_Y 已提交
5357 5358
          if:
              align_corners = False
5359

T
Tink_Y 已提交
5360 5361
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5362

T
Tink_Y 已提交
5363 5364
              H_out = floor(H_{in} * scale_{factor})
              W_out = floor(W_{in} * scale_{factor})
5365

T
Tink_Y 已提交
5366 5367
          else:
              align_corners = True
5368

T
Tink_Y 已提交
5369 5370
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5371

T
Tink_Y 已提交
5372 5373
              H_out = round(H_{in} * scale_{factor})
              W_out = round(W_{in} * scale_{factor})
5374 5375


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

R
ruri 已提交
5379
    Parameters:
5380 5381
        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 已提交
5382
        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.
5383
        scale(float|Variable|None): The multiplier for the input height or width. At
5384 5385 5386
             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 已提交
5387
        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`
5388
        actual_shape(Variable): An optional input to specify output shape
5389 5390
                                dynamically. If provided, image resize
                                according to this given shape rather than
5391
                                :attr:`out_shape` and :attr:`scale` specifying
5392 5393
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
5394 5395 5396 5397 5398
                                :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 已提交
5399
                                errors would be occurred in graph constructing stage.
5400
                                Default: None
5401
        align_corners(bool): ${align_corners_comment}
5402
        data_format (str, optional): Specify the data format of the input, and the data format of the output
5403 5404 5405
            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 已提交
5406 5407

    Returns:
5408
        Variable: 4-D tensor(NCHW or NHWC).
5409 5410 5411

    Examples:
        .. code-block:: python
5412

5413 5414 5415 5416 5417
            #declarative mode
            import paddle.fluid as fluid
            import numpy as np
            import paddle
            paddle.enable_static()
5418

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

5421 5422
            #1
            output = fluid.layers.resize_nearest(input=input,out_shape=[12,12])
R
ruri 已提交
5423

5424 5425 5426 5427 5428
            #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 已提交
5429

5430 5431 5432 5433 5434
            #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 已提交
5435

5436 5437 5438 5439 5440
            #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 已提交
5441

5442 5443 5444
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5445

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

5448
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
5449 5450 5451
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
5452

5453
            print(output_data[0].shape)
R
ruri 已提交
5454

5455 5456 5457 5458 5459 5460 5461 5462
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
5463

5464 5465
            #imperative mode
            import paddle.fluid.dygraph as dg
5466

5467 5468 5469 5470
            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 已提交
5471

5472
                # [2L, 3L, 12L, 12L]
5473 5474 5475



5476 5477
    """

5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'NEAREST',
        actual_shape,
        align_corners,
        align_mode=1,
        data_format=data_format,
    )
5489 5490


5491
def log(x, name=None):
5492
    r"""
W
wanghaoshuang 已提交
5493 5494 5495 5496
    Calculates the natural log of the given input tensor, element-wise.

    .. math::

5497
        Out = \\ln(x)
W
wanghaoshuang 已提交
5498 5499

    Args:
S
Steffy-zxf 已提交
5500
        x (Tensor): Input Tensor. Must be one of the following types: float32, float64.
W
Wilber 已提交
5501
        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`
5502

W
wanghaoshuang 已提交
5503 5504

    Returns:
S
Steffy-zxf 已提交
5505
        Tensor: The natural log of the input Tensor computed element-wise.
W
wanghaoshuang 已提交
5506 5507 5508 5509 5510

    Examples:

        .. code-block:: python

S
Steffy-zxf 已提交
5511
            import paddle
W
Wilber 已提交
5512

S
Steffy-zxf 已提交
5513 5514 5515 5516
            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 已提交
5517
    """
5518
    if in_dygraph_mode():
W
wanghuancoder 已提交
5519
        return _C_ops.log(x)
5520 5521
    if _in_legacy_dygraph():
        return _legacy_C_ops.log(x)
5522

5523
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], "log")
5524
    inputs = {'X': [x]}
W
wanghaoshuang 已提交
5525
    helper = LayerHelper('log', **locals())
W
wanghaoshuang 已提交
5526
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
5527
    out = helper.create_variable_for_type_inference(dtype)
W
wanghaoshuang 已提交
5528
    helper.append_op(type="log", inputs={"X": x}, outputs={"Out": out})
W
wanghaoshuang 已提交
5529 5530 5531
    return out


5532
@deprecated(since="2.0.0", update_to="paddle.nn.functional.relu")
5533
def relu(x, name=None):
W
wanghaoshuang 已提交
5534
    """
Z
zhupengyang 已提交
5535
    ${comment}
W
wanghaoshuang 已提交
5536 5537

    Args:
Z
zhupengyang 已提交
5538 5539 5540 5541
        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 已提交
5542 5543

    Returns:
Z
zhupengyang 已提交
5544
        Variable: ${out_comment}
W
wanghaoshuang 已提交
5545 5546 5547 5548 5549

    Examples:

        .. code-block:: python

5550
            import paddle.fluid as fluid
Z
zhupengyang 已提交
5551 5552 5553 5554 5555 5556 5557
            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. ]
5558
                #  [1.  2.6]]"""
5559 5560

    if in_dygraph_mode():
W
wanghuancoder 已提交
5561
        return _C_ops.relu(x)
5562 5563
    if _in_legacy_dygraph():
        return _legacy_C_ops.relu(x)
5564

5565 5566
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'relu')

5567
    inputs = {'X': [x]}
W
wanghaoshuang 已提交
5568
    helper = LayerHelper('relu', **locals())
W
wanghaoshuang 已提交
5569
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
5570
    out = helper.create_variable_for_type_inference(dtype)
5571 5572 5573
    helper.append_op(
        type="relu", inputs={"X": helper.input('x')}, outputs={"Out": out}
    )
W
wanghaoshuang 已提交
5574
    return out
5575 5576


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

Z
zhupengyang 已提交
5581
    prelu activation.
J
jerrywgz 已提交
5582

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

J
jerrywgz 已提交
5586 5587 5588 5589 5590 5591 5592 5593
    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 已提交
5594 5595
    Parameters:
        x (Tensor): The input Tensor or LoDTensor with data type float32.
5596
        mode (str): The mode for weight sharing.
U
ustiniankw 已提交
5597 5598 5599
        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`.
5600 5601
        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 已提交
5602 5603
        name (str, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.
J
jerrywgz 已提交
5604 5605

    Returns:
U
ustiniankw 已提交
5606
        Tensor, A tensor with the same shape and data type as x.
J
jerrywgz 已提交
5607 5608 5609 5610

    Examples:
        .. code-block:: python

5611
            import paddle
Z
zhupengyang 已提交
5612 5613 5614 5615 5616

            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 已提交
5617

J
jerrywgz 已提交
5618
    """
G
Guoxia Wang 已提交
5619
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'prelu')
5620

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

J
jerrywgz 已提交
5625 5626
    alpha_shape = [1]
    if mode == 'channel':
5627 5628

        true_data_format = [
5629 5630 5631 5632 5633 5634 5635
            'NC',
            'NCL',
            'NCHW',
            'NCDHW',
            'NLC',
            'NHWC',
            'NDHWC',
5636 5637 5638 5639
        ]
        if data_format not in true_data_format:
            raise ValueError(
                "data_format must be one of 'NC', 'NCL', 'NCHW', 'NCDHW', "
5640 5641
                "'NLC', 'NHWC', 'NDHWC' but receive {}".format(data_format)
            )
5642 5643 5644

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

5645 5646 5647 5648
        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:]).
5649
        # To be consistent with Prelu, it is simplified.
5650 5651
        # NOTE(zhiqiu): Revert shape to [1, channel, 1, 1] for compatibility with saved model of old version.
        # NOTE(GuoxiaWang): support NHWC data format
5652
        if data_format == 'NHWC':
5653
            alpha_shape = [1, 1, 1, x.shape[-1]]
5654 5655 5656
        else:
            alpha_shape = [1, x.shape[1], 1, 1]

J
jerrywgz 已提交
5657
    elif mode == 'element':
5658 5659 5660
        assert (
            len(x.shape) >= 1
        ), "The size of input shape should be equal or larger than 1 in prelu() when mode is 'element'"
5661
        alpha_shape = [1] + list(x.shape)[1:]
J
jerrywgz 已提交
5662
    dtype = helper.input_dtype(input_param_name='x')
5663 5664 5665 5666 5667 5668 5669
    alpha = helper.create_parameter(
        attr=helper.param_attr,
        shape=alpha_shape,
        dtype=dtype,
        is_bias=False,
        default_initializer=Constant(0.25),
    )
5670 5671 5672
    if in_dygraph_mode():
        return _C_ops.prelu(x, alpha, data_format, mode)

X
Xin Pan 已提交
5673
    out = helper.create_variable_for_type_inference(dtype)
5674 5675 5676 5677 5678 5679
    helper.append_op(
        type="prelu",
        inputs={"X": x, 'Alpha': alpha},
        attrs={"mode": mode, "data_format": data_format},
        outputs={"Out": out},
    )
5680 5681 5682
    return out


G
fix  
gongweibao 已提交
5683 5684 5685
from paddle.fluid.framework import convert_np_dtype_to_dtype_


5686
@deprecated(since="2.0.0", update_to="paddle.normal")
G
gongweibao 已提交
5687
@templatedoc()
5688 5689 5690
def gaussian_random(
    shape, mean=0.0, std=1.0, seed=0, dtype='float32', name=None
):
G
fix  
gongweibao 已提交
5691
    """
5692 5693
    This OP returns a Tensor filled with random values sampled from a Gaussian
    distribution, with ``shape`` and ``dtype``.
G
fix  
gongweibao 已提交
5694 5695

    Args:
5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710
        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 已提交
5711 5712

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

5716
    Examples:
5717
       .. code-block:: python
5718

5719
            import paddle
5720
            import paddle.fluid as fluid
5721
            paddle.enable_static()
5722 5723

            # example 1:
5724
            # attr shape is a list which doesn't contain Tensor.
5725
            result_1 = fluid.layers.gaussian_random(shape=[3, 4])
5726 5727 5728
            # [[-0.31261674,  1.8736548,  -0.6274357,   0.96988016],
            #  [-0.12294637,  0.9554768,   1.5690808,  -1.2894802 ],
            #  [-0.60082096, -0.61138713,  1.5345167,  -0.21834975]]
5729 5730

            # example 2:
5731 5732 5733
            # 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)
5734
            result_2 = fluid.layers.gaussian_random(shape=[dim_1, dim_2])
5735 5736
            # [[ 0.51398206, -0.3389769,   0.23597084],
            #  [ 1.0388143,  -1.2015356,  -1.0499583 ]]
5737 5738

            # example 3:
5739
            # attr shape is a Tensor, the data type must be int64 or int32.
5740 5741
            var_shape = fluid.data(name='var_shape', shape=[2], dtype="int64")
            result_3 = fluid.layers.gaussian_random(var_shape)
5742 5743 5744 5745
            # if var_shape's value is [2, 3]
            # result_3 is:
            # [[-0.12310527,  0.8187662,   1.923219  ]
            #  [ 0.70721835,  0.5210541,  -0.03214082]]
5746

5747
       .. code-block:: python
5748

5749 5750
           # declarative mode
           # required: skiptest
5751 5752
           import numpy as np
           from paddle import fluid
5753

5754
           x = fluid.layers.gaussian_random((2, 3), std=2., seed=10)
5755

5756 5757 5758 5759
           place = fluid.CPUPlace()
           exe = fluid.Executor(place)
           start = fluid.default_startup_program()
           main = fluid.default_main_program()
5760

5761 5762
           exe.run(start)
           x_np, = exe.run(main, feed={}, fetch_list=[x])
5763

5764 5765 5766 5767 5768 5769 5770 5771 5772 5773
           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
5774

5775 5776 5777
           place = fluid.CPUPlace()
           with dg.guard(place) as g:
               x = fluid.layers.gaussian_random((2, 4), mean=2., dtype="float32", seed=10)
5778
               x_np = x.numpy()
5779 5780 5781
           x_np
           # array([[2.3060477 , 2.676496  , 3.9911983 , 0.9990833 ],
           #        [2.8675377 , 2.2279181 , 0.79029655, 2.8447366 ]], dtype=float32)
G
fix  
gongweibao 已提交
5782
    """
5783 5784
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
5785

5786 5787 5788
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
        place = _current_expected_place()
5789
        return _C_ops.gaussian(
5790 5791
            shape, float(mean), float(std), seed, dtype, place
        )
5792 5793

    if _in_legacy_dygraph():
5794
        shape = utils.convert_shape_to_list(shape)
5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806
        return _legacy_C_ops.gaussian_random(
            'shape',
            shape,
            'mean',
            float(mean),
            'std',
            float(std),
            'seed',
            seed,
            'dtype',
            dtype,
        )
5807 5808 5809

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

    inputs = {}
5812 5813 5814 5815
    attrs = {
        'mean': mean,
        'std': std,
        'seed': seed,
5816
        'dtype': dtype,
5817
        'use_mkldnn': False,
5818
    }
5819 5820 5821
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='gaussian_random/randn'
    )
5822

5823 5824
    helper = LayerHelper('gaussian_random', **locals())
    out = helper.create_variable_for_type_inference(dtype)
5825 5826 5827
    helper.append_op(
        type='gaussian_random', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
G
fix  
gongweibao 已提交
5828 5829 5830 5831

    return out


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

R
ruri 已提交
5837 5838 5839 5840
    Parameters:
        x (Variable): 2-D tensor, [batch_size, input_feature_dimensions]
        min (Float): minimum , default 0.0.
        max (Float): maximum, default 1.0.
5841
        seed (Float): Random seed, default 0. if seed is not 0, will generate same number every time.
G
fix  
gongweibao 已提交
5842
        dtype(np.dtype|core.VarDesc.VarType|str): The type of output data : float32, float_16, int etc
G
fix  
gongweibao 已提交
5843 5844

    Returns:
R
ruri 已提交
5845
        Variable: sampling tensor.
G
fix  
gongweibao 已提交
5846

5847 5848 5849
    Examples:
        .. code-block:: python

5850
            import paddle.fluid as fluid
R
ruri 已提交
5851
            x = fluid.data(
5852 5853
                name="X",
                shape=[13, 11],
R
ruri 已提交
5854
                dtype='float32')
5855

Y
Yibing Liu 已提交
5856
            out = fluid.layers.sampling_id(x)
G
fix  
gongweibao 已提交
5857 5858 5859
    """

    helper = LayerHelper('sampling_id', **locals())
X
Xin Pan 已提交
5860
    out = helper.create_variable_for_type_inference(dtype)
5861 5862 5863 5864 5865 5866
    helper.append_op(
        type='sampling_id',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'min': min, 'max': max, 'seed': seed},
    )
G
fix  
gongweibao 已提交
5867 5868 5869 5870

    return out


G
gongweibao 已提交
5871
@templatedoc()
X
Xin Pan 已提交
5872
def sum(x):
G
fix  
gongweibao 已提交
5873
    """
G
gongweibao 已提交
5874
    ${comment}
5875

5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904
    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 已提交
5905 5906

    Args:
5907
        x (Variable|list(Variable)): ${x_comment}
G
fix  
gongweibao 已提交
5908 5909

    Returns:
5910
        Variable: ${out_comment}
5911 5912 5913 5914

    Examples:
        .. code-block:: python

5915
            import paddle.fluid as fluid
5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934

            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.
5935 5936
            # 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,
5937
            #       and '__int64' on Windows. They both represent 64-bit integer variables.
G
fix  
gongweibao 已提交
5938 5939
    """

S
Steffy-zxf 已提交
5940
    return paddle.add_n(x)
G
fix  
gongweibao 已提交
5941 5942 5943 5944


def shape(input):
    """
5945
    :alias_main: paddle.shape
5946 5947
        :alias: paddle.shape,paddle.tensor.shape,paddle.tensor.attribute.shape
        :old_api: paddle.fluid.layers.shape
5948

C
chengduozh 已提交
5949 5950
    **Shape Layer**

C
fix doc  
chengduozh 已提交
5951
    Get the shape of the input.
G
fix  
gongweibao 已提交
5952

5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969
    .. 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 已提交
5970
    Args:
5971
        input (Variable): The input can be N-D Tensor or SelectedRows with data type bool, float16, float32, float64, int32, int64.
5972
                          If input variable is type of SelectedRows, returns the shape of it's inner tensor.
G
fix  
gongweibao 已提交
5973 5974

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

5977 5978 5979
    Examples:
        .. code-block:: python

5980
            import paddle.fluid as fluid
5981
            import numpy as np
W
Wilber 已提交
5982 5983
            import paddle
            paddle.enable_static()
5984

5985
            inputs = fluid.data(name="x", shape=[3, 100, 100], dtype="float32")
5986 5987 5988 5989 5990 5991 5992 5993 5994
            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 已提交
5995
    """
5996
    if in_dygraph_mode():
5997
        out = _C_ops.shape(input)
5998 5999 6000
        out.stop_gradient = True
        return out
    if _in_legacy_dygraph():
6001
        out = _legacy_C_ops.shape(input)
W
Wilber 已提交
6002 6003 6004
        out.stop_gradient = True
        return out

6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019
    check_variable_and_dtype(
        input,
        'input',
        [
            'bool',
            'float16',
            'float32',
            'float64',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        'shape',
    )
G
fix  
gongweibao 已提交
6020
    helper = LayerHelper('shape', **locals())
6021
    out = helper.create_variable_for_type_inference(dtype='int32')
6022 6023 6024 6025 6026 6027
    helper.append_op(
        type='shape',
        inputs={'Input': input},
        outputs={'Out': out},
        stop_gradient=True,
    )
G
fix  
gongweibao 已提交
6028 6029

    return out
G
merge  
gongweibao 已提交
6030 6031


S
sneaxiy 已提交
6032 6033 6034 6035
def _elementwise_op(helper):
    op_type = helper.layer_type
    x = helper.kwargs.get('x', None)
    y = helper.kwargs.get('y', None)
X
Xin Pan 已提交
6036

S
sneaxiy 已提交
6037 6038
    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)
6039
    check_variable_and_dtype(
6040 6041 6042 6043 6044
        x,
        'x',
        ['float16', 'uint16', 'float32', 'float64', 'int32', 'int64'],
        op_type,
    )
6045
    check_variable_and_dtype(
6046 6047 6048 6049 6050
        y,
        'y',
        ['float16', 'uint16', 'float32', 'float64', 'int32', 'int64'],
        op_type,
    )
6051

S
sneaxiy 已提交
6052 6053
    axis = helper.kwargs.get('axis', -1)
    use_mkldnn = helper.kwargs.get('use_mkldnn', False)
S
sneaxiy 已提交
6054
    name = helper.kwargs.get('name', None)
6055
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
S
sneaxiy 已提交
6056

6057 6058 6059 6060 6061 6062
    helper.append_op(
        type=op_type,
        inputs={'X': x, 'Y': y},
        outputs={'Out': out},
        attrs={'axis': axis, 'use_mkldnn': use_mkldnn},
    )
S
sneaxiy 已提交
6063 6064 6065
    return helper.append_activation(out)


X
Xin Pan 已提交
6066
def elementwise_add(x, y, axis=-1, act=None, name=None):
6067
    """
6068

6069
    Examples:
6070

6071
        .. code-block:: python
6072

6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085
            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
6086

6087 6088 6089 6090
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6091

6092
            print(z_value) # [3., 8., 6.]
6093 6094


6095
        .. code-block:: python
6096

6097 6098 6099
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6100

6101 6102 6103 6104 6105 6106 6107 6108 6109 6110
            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
6111

6112 6113
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6114

6115 6116
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6117

6118
            print(z_value) # z.shape=[2,3,4,5]
6119 6120


6121
        ..  code-block:: python
6122

6123 6124 6125
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6126

6127 6128 6129 6130 6131 6132 6133 6134 6135 6136
            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
6137

6138 6139
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6140

6141 6142 6143
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
6144 6145

    """
J
Jiabin Yang 已提交
6146
    if _non_static_mode():
6147
        return _elementwise_op_in_dygraph(
6148 6149 6150 6151 6152
            x,
            y,
            axis=axis,
            act=act,
            op_name='elementwise_add',
6153 6154
            use_mkldnn=_global_flags()["FLAGS_use_mkldnn"],
        )
6155

S
sneaxiy 已提交
6156 6157 6158
    return _elementwise_op(LayerHelper('elementwise_add', **locals()))


6159
@deprecated(since="2.0.0", update_to="paddle.divide")
X
Xin Pan 已提交
6160
def elementwise_div(x, y, axis=-1, act=None, name=None):
6161
    """
6162

6163
    Examples:
6164

6165
        .. code-block:: python
6166

6167 6168 6169
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6170

6171 6172 6173 6174 6175 6176 6177 6178 6179 6180
            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
6181

6182 6183 6184 6185
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6186

6187
            print(z_value) # [2., 0.6, 2.]
6188 6189


6190
        .. code-block:: python
6191

6192 6193 6194
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6195

6196 6197 6198 6199 6200 6201 6202 6203 6204 6205
            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
6206

6207 6208
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6209

6210 6211
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6212

6213
            print(z_value) # z.shape=[2,3,4,5]
6214 6215


6216
        ..  code-block:: python
6217

6218 6219 6220
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6221

6222 6223 6224 6225 6226 6227 6228 6229 6230 6231
            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
6232

6233 6234
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6235

6236 6237 6238
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
6239 6240

    """
J
Jiabin Yang 已提交
6241
    if _non_static_mode():
6242 6243 6244
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_div'
        )
6245

S
sneaxiy 已提交
6246 6247 6248
    return _elementwise_op(LayerHelper('elementwise_div', **locals()))


X
Xin Pan 已提交
6249
def elementwise_sub(x, y, axis=-1, act=None, name=None):
6250
    """
6251

6252
    Examples:
6253

6254
        .. code-block:: python
6255

6256 6257 6258
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6259

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

6271 6272 6273 6274
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6275

6276
            print(z_value) # [1., -2., 2.]
6277 6278


6279
        .. code-block:: python
6280

6281 6282 6283
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6284

6285 6286 6287 6288 6289 6290 6291 6292 6293 6294
            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
6295

6296 6297
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6298

6299 6300
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6301

6302
            print(z_value) # z.shape=[2,3,4,5]
6303 6304


6305
        ..  code-block:: python
6306

6307 6308 6309
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6310

6311 6312 6313 6314 6315 6316 6317 6318 6319 6320
            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
6321

6322 6323
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6324

6325 6326 6327
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
6328 6329

    """
J
Jiabin Yang 已提交
6330
    if _non_static_mode():
6331 6332 6333
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_sub'
        )
6334

S
sneaxiy 已提交
6335 6336 6337
    return _elementwise_op(LayerHelper('elementwise_sub', **locals()))


6338
@deprecated(since="2.0.0", update_to="paddle.multiply")
X
Xin Pan 已提交
6339
def elementwise_mul(x, y, axis=-1, act=None, name=None):
6340
    """
6341

6342
    Examples:
6343

6344
        .. code-block:: python
6345

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

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

6361 6362 6363 6364
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6365

6366
            print(z_value) # [2., 15., 8.]
6367 6368


6369
        .. code-block:: python
6370

6371 6372 6373
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6374

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

6386 6387
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6388

6389 6390
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6391

6392
            print(z_value) # z.shape=[2,3,4,5]
6393 6394


6395
        ..  code-block:: python
6396

6397 6398 6399
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6400

6401 6402 6403 6404 6405 6406 6407 6408 6409 6410
            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
6411

6412 6413
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6414

6415 6416 6417
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
6418

6419
    """
J
Jiabin Yang 已提交
6420
    if _non_static_mode():
6421 6422 6423
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_mul'
        )
6424

S
sneaxiy 已提交
6425 6426 6427 6428
    return _elementwise_op(LayerHelper('elementwise_mul', **locals()))


for func in [
6429 6430 6431 6432
    elementwise_add,
    elementwise_div,
    elementwise_sub,
    elementwise_mul,
6433 6434
]:
    op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
6435 6436

    # insert the c++ doc string on top of python doc string
6437 6438 6439 6440 6441
    func.__doc__ = (
        _generate_doc_string_(
            op_proto,
            additional_args_lines=[
                "axis (int32, optional): If X.dimension != Y.dimension, \
6442 6443
            Y.dimension must be a subsequence of x.dimension. \
            And axis is the start dimension index for broadcasting Y onto X. ",
6444
                "act (string, optional): Activation applied to the output. \
6445
            Default is None. Details: :ref:`api_guide_activations_en` ",
6446
                "name (string, optional): Name of the output. \
6447
            Default is None. It's used to print debug info for developers. Details: \
6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463
            :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__)
    )
6464

6465 6466 6467
    doc_list = func.__doc__.splitlines()

    for idx, val in enumerate(doc_list):
6468 6469 6470 6471 6472
        if (
            val.startswith("Warning: ")
            and val.endswith(" instead.")
            and "and will be removed in future versions." in val
        ):
6473 6474 6475 6476
            doc_list.insert(0, doc_list.pop(idx))
            func.__doc__ = "\n" + "\n".join(i for i in doc_list)
            break

6477
for func in []:
S
sneaxiy 已提交
6478 6479 6480 6481
    op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
    func.__doc__ = _generate_doc_string_(
        op_proto,
        additional_args_lines=[
S
sneaxiy 已提交
6482
            "act (basestring|None): Activation applied to the output.",
6483 6484 6485 6486 6487 6488
            "name (basestring|None): Name of the output.",
        ],
    )
    func.__doc__ = (
        func.__doc__
        + """
6489 6490 6491

Examples:
  .. code-block:: python
6492

6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522
    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)
6523 6524 6525 6526 6527 6528 6529 6530 6531 6532
    """
        % (
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
        )
    )
M
minqiyang 已提交
6533 6534


6535
def _logical_op(op_name, x, y, out=None, name=None, binary_op=True):
J
Jiabin Yang 已提交
6536
    if _non_static_mode():
6537
        op = getattr(_legacy_C_ops, op_name)
6538 6539 6540 6541
        if binary_op:
            return op(x, y)
        else:
            return op(x)
6542
    check_variable_and_dtype(
6543 6544
        x,
        "x",
6545
        ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
6546 6547
        op_name,
    )
6548
    if y is not None:
6549
        check_variable_and_dtype(
6550 6551
            y,
            "y",
6552
            ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
6553 6554
            op_name,
        )
6555
    if out is not None:
6556
        check_type(out, "out", Variable, op_name)
6557

M
minqiyang 已提交
6558 6559
    helper = LayerHelper(op_name, **locals())

6560 6561 6562
    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."
6563 6564
            % (op_name, x.dtype, y.dtype)
        )
M
minqiyang 已提交
6565 6566

    if out is None:
6567
        out = helper.create_variable_for_type_inference(dtype=x.dtype)
M
minqiyang 已提交
6568 6569

    if binary_op:
6570 6571 6572
        helper.append_op(
            type=op_name, inputs={"X": x, "Y": y}, outputs={"Out": out}
        )
M
minqiyang 已提交
6573 6574 6575 6576 6577 6578
    else:
        helper.append_op(type=op_name, inputs={"X": x}, outputs={"Out": out})

    return out


6579 6580 6581
@templatedoc()
def clip(x, min, max, name=None):
    """
6582
        :old_api: paddle.fluid.layers.clip
6583

6584 6585 6586 6587
    ${comment}

    Args:
        x(${x_type}): ${x_comment}
S
SunGaofeng 已提交
6588 6589
        min(float): ${min_comment}
        max(float): ${max_comment}
6590 6591
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
6592
                             For more information, please refer to :ref:`api_guide_Name`
6593 6594

    Returns:
S
SunGaofeng 已提交
6595 6596 6597 6598
        ${out_comment}

    Return Type:
        ${out_type}
6599 6600 6601 6602

    Examples:
        .. code-block:: python

S
SunGaofeng 已提交
6603
            import paddle.fluid as fluid
S
SunGaofeng 已提交
6604
            input = fluid.data(
6605 6606
                name='data', shape=[1], dtype='float32')
            reward = fluid.layers.clip(x=input, min=-1.0, max=1.0)
6607 6608 6609
    """

    helper = LayerHelper("clip", **locals())
6610
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'clip')
6611 6612

    if name is None:
6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626
        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},
    )
6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638

    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}
6639 6640 6641
        name(str, optional): For detailed information, please refer
            to :ref:`api_guide_Name`. Usually name is no need to set and
            None by default.
6642 6643

    Returns:
6644
        Tensor:
W
wangguanzhong 已提交
6645

6646
        out(${out_type}): ${out_comment}
6647

W
wangguanzhong 已提交
6648

6649 6650 6651
    Examples:
        .. code-block:: python

6652
            import paddle
6653
            import paddle.fluid as fluid
6654

6655 6656 6657
            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]]
6658 6659
    """

L
lyq 已提交
6660
    if in_dygraph_mode():
6661
        return _C_ops.clip_by_norm(x, max_norm)
J
Jiabin Yang 已提交
6662
    if _non_static_mode():
6663
        return _legacy_C_ops.clip_by_norm(x, 'max_norm', max_norm)
6664

6665
    helper = LayerHelper("clip_by_norm", **locals())
6666
    check_variable_and_dtype(x, 'X', ['float32', 'float16'], 'clip_by_norm')
6667
    check_type(max_norm, 'max_norm', (float), 'clip_by_norm')
6668 6669

    if name is None:
6670 6671 6672
        name = unique_name.generate_with_ignorable_key(
            ".".join([helper.name, 'tmp'])
        )
S
sneaxiy 已提交
6673

6674 6675 6676
    out = helper.create_variable(
        type=x.type, name=name, dtype=x.dtype, persistable=False
    )
6677

6678 6679 6680 6681 6682 6683
    helper.append_op(
        type="clip_by_norm",
        inputs={"X": x},
        attrs={"max_norm": max_norm},
        outputs={"Out": out},
    )
6684 6685

    return out
X
Xin Pan 已提交
6686 6687


6688
@deprecated(since="2.0.0", update_to="paddle.mean")
X
Xin Pan 已提交
6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699
@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}
6700 6701 6702 6703

    Examples:
        .. code-block:: python

6704
            import paddle
6705
            import paddle.fluid as fluid
6706 6707
            paddle.enable_static()

6708 6709
            input = fluid.layers.data(
                name='data', shape=[2, 3], dtype='float32')
6710
            mean = paddle.mean(input)
X
Xin Pan 已提交
6711
    """
6712

6713
    if _in_legacy_dygraph():
6714
        return _legacy_C_ops.mean(x)
6715
    if in_dygraph_mode():
6716
        return _C_ops.mean_all(x)
X
Xin Pan 已提交
6717 6718

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

6722 6723 6724
    helper.append_op(
        type="mean", inputs={"X": x}, attrs={}, outputs={"Out": out}
    )
X
Xin Pan 已提交
6725 6726 6727 6728

    return out


C
chengduo 已提交
6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739
@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}
6740 6741 6742 6743

    Examples:
        .. code-block:: python

6744
            import paddle.fluid as fluid
6745 6746 6747 6748 6749
            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 已提交
6750
    """
6751 6752 6753
    if in_dygraph_mode():
        return _C_ops.merge_selected_rows(x)

6754
    if _non_static_mode():
6755
        return _legacy_C_ops.merge_selected_rows(x)
C
chengduo 已提交
6756 6757 6758

    helper = LayerHelper("merge_selected_rows", **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
6759 6760 6761 6762 6763 6764
    helper.append_op(
        type="merge_selected_rows",
        inputs={"X": x},
        attrs={},
        outputs={"Out": out},
    )
C
chengduo 已提交
6765 6766 6767
    return out


X
Xin Pan 已提交
6768 6769
def mul(x, y, x_num_col_dims=1, y_num_col_dims=1, name=None):
    """
L
liu zhengxi 已提交
6770 6771 6772 6773 6774 6775 6776 6777
    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 已提交
6778 6779

    Args:
L
liu zhengxi 已提交
6780 6781
        x (Variable): The first input Tensor/LoDTensor of mul_op.
        y (Variable): The second input Tensor/LoDTensor of mul_op.
6782 6783 6784
        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 已提交
6785 6786

    Returns:
L
liu zhengxi 已提交
6787
        Variable(Tensor/LoDTensor): The output Tensor/LoDTensor of mul op.
6788 6789

    Examples:
L
liu zhengxi 已提交
6790
        ..  code-block:: python
6791

6792
            import paddle.fluid as fluid
6793 6794
            import paddle
            paddle.enable_static()
6795 6796 6797 6798 6799
            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)
6800

6801

X
Xin Pan 已提交
6802
    """
J
Jiabin Yang 已提交
6803
    if _non_static_mode():
6804 6805 6806 6807 6808 6809 6810 6811
        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 已提交
6812

6813 6814
    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 已提交
6815
    helper = LayerHelper("mul", **locals())
6816 6817
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'mul')
    check_variable_and_dtype(y, 'y', ['float16', 'float32', 'float64'], 'mul')
6818
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
X
Xin Pan 已提交
6819

6820 6821 6822
    helper.append_op(
        type="mul", inputs={"X": x, "Y": y}, attrs=attrs, outputs={"Out": out}
    )
X
Xin Pan 已提交
6823 6824 6825
    return out


M
minqiyang 已提交
6826 6827
def hash(input, hash_size, num_hash=1, name=None):
    """
6828

Z
zhupengyang 已提交
6829
    This OP hash the input to an integer less than the hash_size.
M
minqiyang 已提交
6830 6831
    The hash algorithm we used was xxHash - Extremely fast hash algorithm
    (https://github.com/Cyan4973/xxHash/tree/v0.6.5)
M
minqiyang 已提交
6832 6833

    Args:
Z
zhupengyang 已提交
6834 6835 6836 6837 6838 6839
        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 已提交
6840 6841

    Returns:
Z
zhupengyang 已提交
6842
       Variable: A LoDTensor with the same data type as input.
M
minqiyang 已提交
6843 6844

    Examples:
Z
zhupengyang 已提交
6845
        .. code-block:: python
H
haowang101779990 已提交
6846

6847
            import paddle.fluid as fluid
Z
zhupengyang 已提交
6848
            import numpy as np
6849 6850
            import paddle
            paddle.enable_static()
6851

Z
zhupengyang 已提交
6852
            place = fluid.core.CPUPlace()
6853

6854 6855
            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)
6856

Z
zhupengyang 已提交
6857 6858 6859 6860
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
            in1 = np.array([[1,2],[3,4]]).astype("int32")
            print(in1)
6861
            x_i = fluid.create_lod_tensor(in1, [[0, 2]], place)
Z
zhupengyang 已提交
6862 6863 6864 6865 6866 6867 6868 6869 6870 6871
            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 已提交
6872
    """
6873
    check_variable_and_dtype(input, 'input', ['int32', 'int64'], 'hash')
6874 6875
    check_type(hash_size, 'hash_size', int, 'hash')
    check_type(num_hash, 'num_hash', int, 'hash')
M
minqiyang 已提交
6876
    helper = LayerHelper('hash', **locals())
6877 6878 6879 6880 6881 6882 6883 6884 6885
    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 已提交
6886
    return out
G
gmcather 已提交
6887 6888


D
dengkaipeng 已提交
6889
@templatedoc()
6890 6891
def grid_sampler(x, grid, name=None):
    """
6892

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

H
haowang101779990 已提交
6902
    .. code-block:: text
6903

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

K
Kaipeng Deng 已提交
6907 6908 6909 6910
        .. code-block:: text

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

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

H
haowang101779990 已提交
6916 6917 6918 6919 6920 6921 6922 6923 6924
          wn ------- y_n ------- en
          |           |           |
          |          d_n          |
          |           |           |
         x_w --d_w-- grid--d_e-- x_e
          |           |           |
          |          d_s          |
          |           |           |
          ws ------- y_s ------- wn
6925

H
haowang101779990 已提交
6926 6927 6928 6929
        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
6930

H
haowang101779990 已提交
6931 6932 6933 6934
        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
6935

H
haowang101779990 已提交
6936 6937 6938 6939
        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
6940

H
haowang101779990 已提交
6941 6942
        output = wn * d_e * d_s + en * d_w * d_s
               + ws * d_e * d_n + es * d_w * d_n
D
dengkaipeng 已提交
6943 6944

    Args:
K
Kaipeng Deng 已提交
6945 6946 6947 6948 6949 6950 6951 6952 6953
        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 已提交
6954 6955

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

H
haowang101779990 已提交
6960 6961 6962 6963
    Examples:

        .. code-block:: python

K
Kaipeng Deng 已提交
6964
            import paddle.fluid as fluid
6965 6966
            import paddle.fluid as fluid
            import paddle
K
Kaipeng Deng 已提交
6967

6968
            paddle.enable_static()
K
Kaipeng Deng 已提交
6969 6970
            # use with affine_grid
            x = fluid.data(name='x', shape=[None, 10, 32, 32], dtype='float32')
K
Kaipeng Deng 已提交
6971 6972
            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 已提交
6973
            out = fluid.layers.grid_sampler(x=x, grid=grid)
6974

D
dengkaipeng 已提交
6975 6976 6977
    """
    helper = LayerHelper("grid_sampler", **locals())

6978
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'grid_sampler')
6979 6980 6981
    check_variable_and_dtype(
        grid, 'grid', ['float32', 'float64'], 'grid_sampler'
    )
D
dengkaipeng 已提交
6982 6983 6984 6985 6986 6987
    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")

6988
    out = helper.create_variable_for_type_inference(x.dtype)
D
dengkaipeng 已提交
6989 6990
    ipts = {'X': x, 'Grid': grid}

6991 6992
    attrs = {'use_cudnn': False} if core.is_compiled_with_rocm() else {}

6993 6994 6995
    helper.append_op(
        type='grid_sampler', inputs=ipts, outputs={'Output': out}, attrs=attrs
    )
6996 6997 6998
    return out


G
gmcather 已提交
6999
def log_loss(input, label, epsilon=1e-4, name=None):
7000
    r"""
7001

G
gmcather 已提交
7002 7003 7004 7005 7006 7007 7008
    **Negative Log Loss Layer**

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

    .. math::

7009 7010
        Out = -label * \log{(input + \epsilon)}
              - (1 - label) * \log{(1 - input + \epsilon)}
G
gmcather 已提交
7011 7012

    Args:
7013
        input (Tensor|list):  A 2-D tensor with shape [N x 1], where N is the
G
gmcather 已提交
7014
                                batch size. This input is a probability computed
Y
Yibing Liu 已提交
7015
                                by the previous operator. Data type float32.
7016
        label (Tensor|list):  The ground truth which is a 2-D tensor with
7017
                                shape [N x 1], where N is the batch size.
Y
Yibing Liu 已提交
7018 7019
                                Data type float32.
        epsilon (float, optional): A small number for numerical stability. Default 1e-4.
7020
        name(str|None): For detailed information, please refer to
Y
Yibing Liu 已提交
7021
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
G
gmcather 已提交
7022 7023

    Returns:
7024
        Tensor, which shape is [N x 1], data type is float32.
G
gmcather 已提交
7025 7026 7027 7028

    Examples:
        .. code-block:: python

7029 7030 7031 7032 7033 7034
          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 已提交
7035
    """
7036
    return paddle.nn.functional.log_loss(input, label, epsilon, name)
G
gmcather 已提交
7037 7038


7039 7040 7041
def bilinear_tensor_product(
    x, y, size, act=None, name=None, param_attr=None, bias_attr=None
):
7042
    r"""
7043 7044
    :api_attr: Static Graph

Y
Yibing Liu 已提交
7045
    **Bilinear Tensor Product Layer**
Q
Qiao Longfei 已提交
7046

Q
Qiao Longfei 已提交
7047
    This layer performs bilinear tensor product on two inputs.
Q
Qiao Longfei 已提交
7048 7049 7050
    For example:

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

Q
Qiao Longfei 已提交
7053
    In this formula:
7054 7055
      - :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 已提交
7056
      - :math:`W_{i}`: the i-th learned weight, shape is [M, N].
H
haowang101779990 已提交
7057
      - :math:`out_{i}`: the i-th element of out, shape is [batch_size, size].
Q
Qiao Longfei 已提交
7058 7059 7060
      - :math:`y^\mathrm{T}`: the transpose of :math:`y_{2}`.

    Args:
7061
        x (Variable): 2-D input tensor with shape [batch_size, M]. Data type
Y
Yibing Liu 已提交
7062
            is float32 or float64.
7063
        y (Variable): 2-D input tensor with shape [batch_size, N]. Data type
Y
Yibing Liu 已提交
7064
            should be same as **x**.
Q
Qiao Longfei 已提交
7065
        size (int): The dimension of this layer.
Y
Yibing Liu 已提交
7066
        act (str|None): Activation to be applied to the output of this layer. Default None.
7067
        name(str|None): For detailed information, please refer to
Y
Yibing Liu 已提交
7068
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
7069 7070
        param_attr (ParamAttr|None): To specify the weight parameter attribute.
            Default: None, which means the default weight parameter property is
Y
Yibing Liu 已提交
7071
            used. See usage for details in :ref:`api_fluid_ParamAttr` .
7072 7073
        bias_attr (ParamAttr|None): To specify the bias parameter attribute.
            Default: None, which means the default bias parameter property is
Y
Yibing Liu 已提交
7074
            used. See usage for details in :ref:`api_fluid_ParamAttr` .
Q
Qiao Longfei 已提交
7075
    Returns:
Y
Yibing Liu 已提交
7076
        Variable: A 2-D Tensor of shape [batch_size, size]. Data type is the same as input **x**.
Q
Qiao Longfei 已提交
7077 7078 7079 7080

    Examples:
        .. code-block:: python

7081 7082 7083 7084 7085
            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 已提交
7086 7087
    """
    helper = LayerHelper('bilinear_tensor_product', **locals())
Q
Qiao Longfei 已提交
7088
    dtype = helper.input_dtype('x')
Q
Qiao Longfei 已提交
7089 7090 7091

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

7092 7093 7094
    w = helper.create_parameter(
        attr=helper.param_attr, shape=param_shape, dtype=dtype, is_bias=False
    )
7095
    out = helper.create_variable_for_type_inference(dtype=dtype)
Q
Qiao Longfei 已提交
7096 7097 7098 7099

    inputs = {"X": x, "Y": y, "Weight": w}
    if helper.bias_attr:
        bias_size = [1, size]
7100 7101 7102
        bias = helper.create_parameter(
            attr=helper.bias_attr, shape=bias_size, dtype=dtype, is_bias=True
        )
Q
Qiao Longfei 已提交
7103
        inputs["Bias"] = bias
7104 7105 7106
    helper.append_op(
        type="bilinear_tensor_product", inputs=inputs, outputs={"Out": out}
    )
Q
Qiao Longfei 已提交
7107 7108 7109

    # add activation
    return helper.append_activation(out)
C
chengduo 已提交
7110 7111 7112 7113 7114


@templatedoc()
def get_tensor_from_selected_rows(x, name=None):
    """
7115 7116 7117 7118 7119 7120 7121 7122 7123
    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]]

7124
        Output is LoDTensor:
7125 7126 7127 7128 7129 7130
           out.shape = [5, 2]
           out.data = [[1, 1],
                       [2, 2],
                       [2, 2],
                       [3, 3],
                       [6, 6]]
C
chengduo 已提交
7131 7132

    Args:
7133 7134 7135
        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 已提交
7136 7137

    Returns:
7138
        Variable: LoDTensor transformed from SelectedRows. The data type is same with input.
B
bdzhuxiaoning 已提交
7139 7140 7141

    Examples:
        .. code-block:: python
7142

B
bdzhuxiaoning 已提交
7143 7144 7145 7146
            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 已提交
7147 7148
    """

7149 7150 7151 7152 7153
    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 已提交
7154 7155
    helper = LayerHelper('get_tensor_from_selected_rows', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
7156 7157 7158 7159 7160 7161
    helper.append_op(
        type='get_tensor_from_selected_rows',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={},
    )
C
chengduo 已提交
7162
    return out
7163 7164


7165
@templatedoc()
7166
def temporal_shift(x, seg_num, shift_ratio=0.25, name=None, data_format="NCHW"):
7167
    """
7168

7169
    **Temporal Shift Operator**
7170

7171
    ${comment}
7172 7173

    Args:
7174
        x(Tensor): ${x_comment}
7175
        seg_num(int): ${seg_num_comment}
D
dengkaipeng 已提交
7176
        shift_ratio(float): ${shift_ratio_comment}
K
Kaipeng Deng 已提交
7177 7178 7179
        name(str, optional): For detailed information, please refer
                             to :ref:`api_guide_Name`. Usually name is no need to set and
                             None by default.
7180 7181
        data_format(str, optional): Data format that specifies the layout of input.
            It can be "NCHW" or "NHWC". Default: "NCHW".
7182 7183

    Returns:
7184
        out(Tensor): The temporal shifting result is a tensor with the
K
Kaipeng Deng 已提交
7185
        same shape and same data type as the input.
7186 7187 7188 7189 7190 7191 7192

    Raises:
        TypeError: seg_num must be int type.

    Examples:
        .. code-block:: python

7193 7194 7195 7196
            import paddle
            import paddle.nn.functional as F

            input = paddle.randn([6, 4, 2, 2])
7197
            out = F.temporal_shift(x=input, seg_num=2, shift_ratio=0.2)
7198
    """
7199 7200 7201
    return paddle.nn.functional.temporal_shift(
        x, seg_num, shift_ratio, name, data_format
    )
7202 7203


7204
class PyFuncRegistry:
S
sneaxiy 已提交
7205 7206 7207
    _register_funcs = []

    def __init__(self, func):
S
sneaxiy 已提交
7208
        if func is None or not callable(func):
S
sneaxiy 已提交
7209 7210 7211
            raise TypeError('func must be a Python function')

        self._func = func
M
minqiyang 已提交
7212
        # find named args using reflection
7213
        args = inspect.getfullargspec(self._func)
S
sneaxiy 已提交
7214 7215 7216 7217 7218 7219
        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 已提交
7220 7221 7222
        '''
        Why record self here?

M
minqiyang 已提交
7223 7224
        1. For debug usage. Users can call
           :code:`py_func.registered_func(idx)` method
S
sneaxiy 已提交
7225
           to find the registered function corresponding
M
minqiyang 已提交
7226
           to :code:`idx`.
S
sneaxiy 已提交
7227

M
minqiyang 已提交
7228 7229
        2. For increasing reference count of self.
           It seems that to release Python object
S
sneaxiy 已提交
7230
           whose reference count is 1 would cause
M
minqiyang 已提交
7231
           segmentation fault error in C++ side.
S
sneaxiy 已提交
7232 7233
           May be lack of Python GC in C++ side?
        '''
S
sneaxiy 已提交
7234
        PyFuncRegistry._register_funcs.append(self)
S
sneaxiy 已提交
7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248

    @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 已提交
7249 7250 7251 7252 7253 7254 7255 7256 7257
        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 已提交
7258

S
sneaxiy 已提交
7259
        if not isinstance(func_ret, (list, tuple)):
7260
            func_ret = (func_ret,)
S
sneaxiy 已提交
7261 7262

        ret = []
S
sneaxiy 已提交
7263 7264 7265
        for each_ret in func_ret:
            if each_ret is None or isinstance(each_ret, core.LoDTensor):
                ret.append(each_ret)
S
sneaxiy 已提交
7266 7267
                continue

S
sneaxiy 已提交
7268 7269
            if not isinstance(each_ret, np.ndarray):
                each_ret = np.array(each_ret)
S
sneaxiy 已提交
7270

S
sneaxiy 已提交
7271 7272 7273
            tensor = core.LoDTensor()
            tensor.set(each_ret, core.CPUPlace())
            ret.append(tensor)
S
sneaxiy 已提交
7274

S
sneaxiy 已提交
7275
        return tuple(ret)
S
sneaxiy 已提交
7276 7277


7278
@static_only
S
sneaxiy 已提交
7279 7280 7281
@templatedoc()
def py_func(func, x, out, backward_func=None, skip_vars_in_backward_input=None):
    """
7282 7283
    :api_attr: Static Graph

7284 7285
    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
7286 7287
    other easily. So you can use Python and numpy API to register a python OP.

7288 7289
    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
7290
    call ``backward_func`` at backward runtime(if ``backward_func`` is not  None).
7291 7292
    ``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.
7293

7294
    The input of the backward function ``backward_func`` is ``x``, ``out`` and
7295 7296 7297
    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``.
7298

7299 7300
    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
7301 7302 7303 7304 7305 7306 7307
    ``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
7308 7309
            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
7310
            actively convert Tensor into a numpy array, so that we can use Python and
7311
            numpy API arbitrarily. If not, some operations of numpy may not be compatible.
7312 7313 7314 7315 7316 7317 7318
        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.
7319 7320 7321
        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
7322
            ``x`` when the network is at backward runtime.
7323 7324
        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].
7325
            It must belong to either ``x`` or ``out``. The default  value is None, which means
7326 7327
            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
7328
            useful when ``backward_func`` is not None.
7329 7330

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

    Examples:
7334
        .. code-block:: python
7335

7336
            # example 1:
7337
            import paddle
7338
            import numpy as np
7339

7340 7341 7342
            paddle.enable_static()

            # Creates a forward function, Tensor can be input directly without
7343
            # being converted into numpy array.
7344 7345 7346
            def tanh(x):
                return np.tanh(x)

7347
            # Skip x in backward function and return the gradient of x
7348
            # Tensor must be actively converted to numpy array, otherwise,
7349
            # operations such as +/- can't be used.
7350 7351
            def tanh_grad(y, dy):
                return np.array(dy) * (1 - np.square(np.array(y)))
7352

7353
            # Creates a forward function for debugging running networks(print value)
7354 7355
            def debug_func(x):
                print(x)
7356

7357
            def create_tmp_var(name, dtype, shape):
7358
                return paddle.static.default_main_program().current_block().create_var(
7359
                    name=name, dtype=dtype, shape=shape)
7360 7361 7362

            def simple_net(img, label):
                hidden = img
7363
                for idx in range(4):
7364
                    hidden = paddle.static.nn.fc(hidden, size=200)
7365 7366 7367
                    new_hidden = create_tmp_var(name='hidden_{}'.format(idx),
                        dtype=hidden.dtype, shape=hidden.shape)

7368
                    # User-defined forward and backward
7369
                    hidden = paddle.static.py_func(func=tanh, x=hidden,
7370 7371 7372
                        out=new_hidden, backward_func=tanh_grad,
                        skip_vars_in_backward_input=hidden)

7373
                    # User-defined debug functions that print out the input Tensor
7374
                    paddle.static.py_func(func=debug_func, x=hidden, out=None)
7375

7376
                prediction = paddle.static.nn.fc(hidden, size=10, activation='softmax')
7377 7378 7379 7380
                ce_loss = paddle.nn.loss.CrossEntropyLoss()
                return ce_loss(prediction, label)

            x = paddle.static.data(name='x', shape=[1,4], dtype='float32')
7381
            y = paddle.static.data(name='y', shape=[1], dtype='int64')
7382 7383 7384 7385 7386
            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')
7387
            input2 = np.random.randint(1, 10, size=[1], dtype='int64')
7388 7389 7390 7391 7392 7393
            out = exe.run(paddle.static.default_main_program(),
                          feed={'x':input1, 'y':input2},
                          fetch_list=[res.name])
            print(out)

        .. code-block:: python
7394

7395
            # example 2:
7396
            # This example shows how to turn Tensor into numpy array and
7397
            # use numpy API to register an Python OP
7398
            import paddle
7399 7400
            import numpy as np

7401 7402
            paddle.enable_static()

7403
            def element_wise_add(x, y):
7404
                # Tensor must be actively converted to numpy array, otherwise,
7405
                # numpy.shape can't be used.
7406
                x = np.array(x)
7407 7408 7409 7410 7411 7412 7413 7414 7415 7416 7417 7418 7419
                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):
7420
                return paddle.static.default_main_program().current_block().create_var(
7421 7422 7423
                            name=name, dtype=dtype, shape=shape)

            def py_func_demo():
7424 7425
                start_program = paddle.static.default_startup_program()
                main_program = paddle.static.default_main_program()
7426 7427

                # Input of the forward function
7428 7429
                x = paddle.static.data(name='x', shape=[2,3], dtype='int32')
                y = paddle.static.data(name='y', shape=[2,3], dtype='int32')
7430

7431 7432 7433 7434
                # 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]
7435
                paddle.static.py_func(func=element_wise_add, x=[x,y], out=output)
7436

7437
                exe=paddle.static.Executor(paddle.CPUPlace())
7438 7439 7440 7441 7442
                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')
7443
                out = exe.run(main_program,
7444 7445 7446 7447 7448 7449 7450 7451 7452
                            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 已提交
7453
    """
S
sneaxiy 已提交
7454
    helper = LayerHelper('py_func', **locals())
7455
    check_type(x, 'X', (list, tuple, Variable, type(None)), 'py_func')
S
sneaxiy 已提交
7456 7457 7458
    if x is None:
        x = []
    elif isinstance(x, Variable):
S
sneaxiy 已提交
7459
        x = [x]
7460 7461 7462
    elif isinstance(x, tuple):
        x = list(x)
    elif not isinstance(x, (list, tuple, Variable)):
S
sneaxiy 已提交
7463
        raise TypeError('Input must be Variable/list(Variable)/tuple(Variable)')
7464
    check_type(out, 'Out', (list, tuple, Variable, type(None)), 'py_func')
S
sneaxiy 已提交
7465 7466 7467
    if out is None:
        out_list = []
    elif isinstance(out, Variable):
S
sneaxiy 已提交
7468
        out_list = [out]
7469 7470
    elif isinstance(out, tuple):
        out_list = list(out)
7471 7472 7473
    elif isinstance(out, list):
        out_list = out
    else:
S
sneaxiy 已提交
7474
        raise TypeError(
7475 7476
            'Output must be Variable/list(Variable)/tuple(Variable)'
        )
S
sneaxiy 已提交
7477

S
sneaxiy 已提交
7478
    fwd_func_id = PyFuncRegistry(func).id
7479 7480 7481
    bwd_func_id = (
        PyFuncRegistry(backward_func).id if backward_func is not None else -1
    )
S
sneaxiy 已提交
7482 7483

    for each_out in out_list:
S
sneaxiy 已提交
7484 7485
        if len(each_out.shape) == 0:
            raise ValueError(
S
sneaxiy 已提交
7486 7487
                'Output shapes of py_func op should be provided by users manually'
            )
S
sneaxiy 已提交
7488

S
sneaxiy 已提交
7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500
    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(
7501 7502 7503 7504
                    'Variable {} is not found in forward inputs and outputs'.format(
                        v.name
                    )
                )
S
sneaxiy 已提交
7505
            backward_skip_vars.add(v.name)
S
sneaxiy 已提交
7506

7507 7508 7509 7510 7511 7512 7513 7514 7515 7516
    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 已提交
7517
    return out
S
sneaxiy 已提交
7518 7519 7520


# For debug usage
S
sneaxiy 已提交
7521 7522 7523 7524
py_func.registered_func = PyFuncRegistry.registered_func
py_func.registered_func_num = PyFuncRegistry.registered_func_num


R
ruri 已提交
7525 7526 7527
def pixel_shuffle(x, upscale_factor):
    """

R
ruri 已提交
7528
    This op rearranges elements in a tensor of shape [N, C, H, W]
R
ruri 已提交
7529 7530 7531
    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.
7532
    Please refer to the paper: `Real-Time Single Image and Video Super-Resolution
R
ruri 已提交
7533 7534 7535
    Using an Efficient Sub-Pixel Convolutional Neural Network <https://arxiv.org/abs/1609.05158v2>`_ .
    by Shi et. al (2016) for more details.

R
ruri 已提交
7536
    Parameters:
R
ruri 已提交
7537

R
ruri 已提交
7538 7539
        x(Variable): 4-D tensor, the data type should be float32 or float64.
        upscale_factor(int): factor to increase spatial resolution.
R
ruri 已提交
7540 7541

    Returns:
7542
        Out(Variable): Reshaped tensor according to the new dimension.
R
ruri 已提交
7543 7544 7545 7546 7547 7548 7549

    Raises:
        ValueError: If the square of upscale_factor cannot divide the channels of input.

    Examples:
        .. code-block:: python

7550 7551 7552 7553 7554 7555 7556 7557
            # 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())
7558

7559 7560
            input_data = np.random.rand(2,9,4,4).astype("float32")
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
7561 7562 7563
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
7564

7565 7566
            # print(output.shape)
            # (2L, 1L, 12L, 12L)
R
ruri 已提交
7567 7568 7569

    """

R
ruri 已提交
7570
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'pixel_shuffle')
R
ruri 已提交
7571 7572 7573 7574 7575 7576 7577
    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")

7578 7579 7580 7581 7582 7583
    helper.append_op(
        type="pixel_shuffle",
        inputs={"X": x},
        outputs={"Out": out},
        attrs={"upscale_factor": upscale_factor},
    )
R
ruri 已提交
7584 7585 7586
    return out


7587 7588 7589 7590 7591
def fsp_matrix(x, y):
    """

    **FSP matrix op**

7592
    This op is used to calculate the flow of solution procedure (FSP) matrix of two 4-D Tensor feature maps.
7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603
    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:

7604 7605 7606
        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].
7607
                      The y_channel can be different with the x_channel of Input(X)
7608 7609
                      while the other dimensions must be the same with Input(X)'s. A Tensor with
                      type float32, float64.
7610 7611 7612 7613

    Returns:

        fsp matrix (Variable): The output of FSP op with shape [batch_size, x_channel, y_channel].
7614 7615
        The x_channel is the channel of x and the y_channel is the channel of y. A Tensor with
        type float32, float64.
7616 7617 7618 7619 7620

    Examples:

        .. code-block:: python

B
Bai Yifan 已提交
7621
            import paddle.fluid as fluid
B
Bai Yifan 已提交
7622
            data = fluid.data(name='data', shape=[None, 3, 32, 32])
B
Bai Yifan 已提交
7623 7624 7625 7626
            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)
7627 7628 7629
            loss = fluid.layers.fsp_matrix(feature_map_0, feature_map_1)

    """
7630 7631
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'fsp_matrix')
    check_variable_and_dtype(y, 'y', ['float32', 'float64'], 'fsp_matrix')
7632
    helper = LayerHelper('fsp_matrix', **locals())
7633 7634 7635
    out = helper.create_variable_for_type_inference(
        dtype=helper.input_dtype(input_param_name='x')
    )
7636 7637
    helper.append_op(type='fsp', inputs={'X': x, 'Y': y}, outputs={'Out': out})
    return out
H
heqiaozhi 已提交
7638 7639 7640


def continuous_value_model(input, cvm, use_cvm=True):
7641
    r"""
H
fix doc  
heqiaozhi 已提交
7642

H
heqiaozhi 已提交
7643
    **continuous_value_model layers**
H
fix doc  
heqiaozhi 已提交
7644

Z
zhoushiyu 已提交
7645
    Now, this OP is used in CTR project to remove or dispose show and click value in :attr:`input`.
H
fix doc  
heqiaozhi 已提交
7646

Z
zhoushiyu 已提交
7647 7648
    :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 已提交
7649
    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 已提交
7650 7651
    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 已提交
7652

Z
zhoushiyu 已提交
7653 7654 7655 7656 7657 7658 7659
    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 已提交
7660

H
heqiaozhi 已提交
7661
    Returns:
H
fix doc  
heqiaozhi 已提交
7662

Z
zhoushiyu 已提交
7663 7664
        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 已提交
7665

H
heqiaozhi 已提交
7666
    Examples:
H
fix doc  
heqiaozhi 已提交
7667

H
heqiaozhi 已提交
7668
        .. code-block:: python
H
fix doc  
heqiaozhi 已提交
7669

7670
          import paddle.fluid as fluid
Z
zhoushiyu 已提交
7671 7672
          input = fluid.data(name="input", shape=[64, 1], dtype="int64")
          label = fluid.data(name="label", shape=[64, 1], dtype="int64")
H
heqiaozhi 已提交
7673 7674 7675 7676 7677 7678 7679 7680
          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 已提交
7681

H
heqiaozhi 已提交
7682 7683 7684
    """
    helper = LayerHelper('cvm', **locals())
    out = helper.create_variable(dtype=input.dtype)
7685 7686 7687 7688 7689 7690 7691 7692 7693
    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 已提交
7694
    return out
Z
zhoukunsheng 已提交
7695 7696 7697 7698 7699 7700 7701


def where(condition):
    """
    Return an int64 tensor with rank 2, specifying the coordinate of true element in `condition`.

    Args:
7702
        condition(Variable): A bool tensor with rank at least 1, the data type is bool.
Z
zhoukunsheng 已提交
7703 7704

    Returns:
7705
        Variable, the output data type is int64. : The tensor variable storing a 2-D tensor, which involves all coordinate.
Z
zhoukunsheng 已提交
7706 7707 7708 7709

    Examples:
        .. code-block:: python

7710
             import paddle.fluid as fluid
7711 7712 7713
             import paddle.fluid.layers as layers
             import numpy as np

Z
zhoukunsheng 已提交
7714
             # condition is a tensor [True, False, True]
7715 7716 7717
             condition = layers.assign(np.array([1, 0, 1], dtype='int32'))
             condition = layers.cast(condition, 'bool')
             out = layers.where(condition) # [[0], [2]]
Z
zhoukunsheng 已提交
7718 7719

             # condition is a tensor [[True, False], [False, True]]
7720 7721 7722
             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 已提交
7723 7724

             # condition is a tensor [False, False, False]
7725 7726 7727 7728
             condition = layers.assign(np.array([0, 0, 0], dtype='int32'))
             condition = layers.cast(condition, 'bool')
             out = layers.where(condition) # [[]]

Z
zhoukunsheng 已提交
7729
    """
H
hong 已提交
7730 7731

    if in_dygraph_mode():
7732
        return _C_ops.nonzero(condition)
7733 7734
    if _in_legacy_dygraph():
        return _legacy_C_ops.where_index(condition)
7735

W
wanghuancoder 已提交
7736 7737
    helper = LayerHelper("where_index", **locals())

Z
zhoukunsheng 已提交
7738
    out = helper.create_variable_for_type_inference(
7739 7740 7741 7742 7743 7744 7745 7746
        dtype=core.VarDesc.VarType.INT64
    )

    helper.append_op(
        type='where_index',
        inputs={'Condition': condition},
        outputs={'Out': [out]},
    )
Z
zhoukunsheng 已提交
7747
    return out
Z
zhoukunsheng 已提交
7748 7749


W
WangXi 已提交
7750
@deprecated(since="2.0.0", update_to="paddle.sign")
Z
zhoukunsheng 已提交
7751
def sign(x):
7752
    r"""
7753
    This OP returns sign of every element in `x`: 1 for positive, -1 for negative and 0 for zero.
Z
zhoukunsheng 已提交
7754 7755

    Args:
7756 7757
        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 已提交
7758 7759

    Returns:
7760
        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 已提交
7761 7762 7763 7764

    Examples:
        .. code-block:: python

7765 7766 7767
          import paddle.fluid as fluid
          import numpy as np

7768
          # [1.0, 0.0, -1.0]
7769
          data = fluid.layers.sign(np.array([3.0, 0.0, -2.0], dtype='float32'))
Z
zhoukunsheng 已提交
7770 7771 7772
    """

    helper = LayerHelper("sign", **locals())
7773 7774 7775 7776
    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 已提交
7777 7778 7779 7780 7781
    out = helper.create_variable_for_type_inference(dtype=x.dtype)

    helper.append_op(type='sign', inputs={'X': [x]}, outputs={'Out': [out]})

    return out
7782 7783


Z
zhoukunsheng 已提交
7784
def unique(x, dtype='int32'):
7785
    r"""
Z
zhoukunsheng 已提交
7786 7787 7788
    Return a unique tensor for `x` and an index tensor pointing to this unique tensor.

    Args:
Z
Zhang Ting 已提交
7789 7790
        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 已提交
7791 7792 7793 7794 7795 7796 7797 7798 7799 7800

    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 已提交
7801
             x = fluid.layers.assign(np.array([2, 3, 3, 1, 5, 3], dtype='int32'))
Z
zhoukunsheng 已提交
7802 7803 7804
             out, index = fluid.layers.unique(x) # out is [2, 3, 1, 5]; index is [0, 1, 1, 2, 3, 1]
    """

7805 7806 7807
    check_variable_and_dtype(
        x, "x", ['float32', 'float64', 'int32', 'int64'], "unique"
    )
Z
zhoukunsheng 已提交
7808 7809 7810 7811 7812 7813
    helper = LayerHelper("unique", **locals())

    out = helper.create_variable_for_type_inference(dtype=x.dtype)

    index = helper.create_variable_for_type_inference(dtype)

7814 7815 7816 7817 7818 7819
    helper.append_op(
        type='unique',
        inputs={'X': x},
        attrs={'dtype': convert_np_dtype_to_dtype_(dtype)},
        outputs={'Out': [out], 'Index': [index]},
    )
Z
zhoukunsheng 已提交
7820 7821 7822 7823

    return out, index


7824
def unique_with_counts(x, dtype='int32'):
7825
    r"""
T
tianshuo78520a 已提交
7826
    This OP return a unique tensor for `x` , and count tensor that the count of unique result in raw input, \
7827
    and an index tensor pointing to this unique tensor.
7828

7829
    **NOTICE**: This op support the variable type of Tensor only.
7830 7831

    Args:
7832
        x(Variable): A 1-D input tensor with input shape of :math:`[N]` , the input data type is float32, float64, int32, int64.
7833
        dtype(np.dtype|core.VarDesc.VarType|str): The type of count and index tensor, it could be int32, int64. Default value is int32.
7834

7835
    Returns:
7836 7837 7838
        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 已提交
7839
        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\
7840
        the :attr:`x`, the data shape is :math:`[K]`, the data shape is the same as output :attr:`out`.
7841 7842 7843 7844 7845 7846 7847 7848 7849

    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]
7850
            # x.shape=(6,) out.shape=(4,), index.shape=(6,), count.shape=(4,)
7851
    """
7852 7853 7854
    check_variable_and_dtype(
        x, "x", ['float32', 'float64', 'int32', 'int64'], "unique_with_counts"
    )
7855 7856
    if not (dtype == 'int32' or dtype == 'int64'):
        raise TypeError(
7857 7858
            "Op unique_with_counts, index dtype must be int32 or int64"
        )
7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872

    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)

7873 7874 7875 7876 7877 7878
    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]},
    )
7879 7880 7881 7882

    return out, index, count


7883
def unfold(x, kernel_sizes, strides=1, paddings=0, dilations=1, name=None):
7884
    r"""
7885

S
SunGaofeng 已提交
7886
    This op returns a col buffer of sliding local blocks of input x, also known
7887
    as im2col for batched 2D image tensors. For each block under the convolution filter,
T
tianshuo78520a 已提交
7888
    all element will be rearranged as a column. While the convolution filter sliding over
7889 7890
    the input feature map, a series of such columns will be formed.

S
SunGaofeng 已提交
7891
    For each input :math:`x` with shape [N, C, H, W], the output shape [N, Cout, Lout]
7892 7893 7894 7895
    can be calculated as following.

    .. math::

7896
        dkernel[0] &= dilations[0] \times (kernel\_sizes[0] - 1) + 1
7897

7898
        dkernel[1] &= dilations[1] \times (kernel\_sizes[1] - 1) + 1
7899

7900
        hout &= \frac{H + paddings[0] + paddings[2] - dkernel[0]}{strides[0]} + 1
7901

7902
        wout &= \frac{W + paddings[1] + paddings[3] - dkernel[1]}{strides[1]} + 1
7903

7904
        Cout &= C \times kernel\_sizes[0] \times kernel\_sizes[1]
7905

7906
        Lout &= hout \times wout
7907 7908


S
SunGaofeng 已提交
7909
    Parameters:
7910
        x(Tensor):              4-D Tensor, input tensor of format [N, C, H, W],
S
SunGaofeng 已提交
7911
                                  data type can be float32 or float64
7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923
        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 已提交
7924
        dilations(int|list):      the dilations of convolution kernel, should be
T
tianshuo78520a 已提交
7925
                                  [dilation_h, dilation_w], or an integer dilation treated as
7926
                                  [dilation, dilation]. For default, it will be [1, 1].
7927 7928
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
7929
                             For more information, please refer to :ref:`api_guide_Name`
7930

7931

7932
    Returns:
7933
        The tensor corresponding to the sliding local blocks.
7934 7935 7936
        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 已提交
7937 7938 7939
        The data type of output is the same as the input :math:`x`

    Return Type:
7940
        Tensor
7941 7942 7943 7944 7945

    Examples:

        .. code-block:: python

7946 7947 7948 7949 7950
            import paddle
            import paddle.nn.functional as F

            x = paddle.randn((100,3,224,224))
            y = F.unfold(x, [3, 3], 1, 1, 1)
7951 7952
    """

7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972
    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,
):
7973
    r"""
7974

7975
    Deformable ROI Pooling Layer
7976

7977
    Performs deformable region-of-interest pooling on inputs. As described
7978
    in `Deformable Convolutional Networks <https://arxiv.org/abs/1703.06211>`_, it will get offset for each bin after
7979
    roi pooling so that pooling at correct region. Batch_size will change to the number of region bounding boxes after deformable_roi_pooling.
7980

7981
    The operation has three steps:
7982

7983
    1. Dividing each region proposal into equal-sized sections with the pooled_width and pooled_height.
7984

7985 7986
    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.
7987

7988
    3. Sample several points in each bin to get average values as output.
7989 7990


7991 7992 7993 7994 7995 7996 7997 7998 7999
    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.
8000 8001 8002
        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.
8003 8004 8005 8006
        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.
8007
        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
8008
                          is k1 * k2 * (C + 1), which k1 and k2 are group width and height and C+1 is number of output
T
tianshuo78520a 已提交
8009
                          channels.) eg.(4, 6), which 4 is height of group and 6 is width of group. Default: [1, 1].
8010 8011 8012 8013 8014 8015 8016
        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 已提交
8017
                                   If value is True, input dimension should be output dimension * pooled_height * pooled_width. Default: False.
8018 8019 8020 8021
        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 已提交
8022 8023 8024 8025

    Examples:
      .. code-block:: python

8026 8027
        # position_sensitive=True
        import paddle.fluid as fluid
C
chengjuntao 已提交
8028
        input = fluid.data(name="input",
8029 8030
                           shape=[2, 192, 64, 64],
                           dtype='float32')
C
chengjuntao 已提交
8031 8032
        rois = fluid.data(name="rois",
                          shape=[-1, 4],
8033
                          dtype='float32',
C
chengjuntao 已提交
8034 8035
                          lod_level=1)
        trans = fluid.data(name="trans",
8036 8037 8038 8039 8040
                           shape=[2, 384, 64, 64],
                           dtype='float32')
        x = fluid.layers.deformable_roi_pooling(input=input,
                                                rois=rois,
                                                trans=trans,
C
chengjuntao 已提交
8041
                                                no_trans=False,
8042
                                                spatial_scale=1.0,
C
chengjuntao 已提交
8043 8044 8045 8046
                                                group_size=(1, 1),
                                                pooled_height=8,
                                                pooled_width=8,
                                                part_size=(8, 8),
8047
                                                sample_per_part=4,
C
chengjuntao 已提交
8048 8049
                                                trans_std=0.1,
                                                position_sensitive=True)
8050

8051
        # position_sensitive=False
8052
        import paddle.fluid as fluid
C
chengjuntao 已提交
8053
        input = fluid.data(name="input",
8054 8055
                           shape=[2, 192, 64, 64],
                           dtype='float32')
C
chengjuntao 已提交
8056 8057
        rois = fluid.data(name="rois",
                          shape=[-1, 4],
8058
                          dtype='float32',
C
chengjuntao 已提交
8059 8060
                          lod_level=1)
        trans = fluid.data(name="trans",
8061 8062 8063 8064 8065
                           shape=[2, 384, 64, 64],
                           dtype='float32')
        x = fluid.layers.deformable_roi_pooling(input=input,
                                                rois=rois,
                                                trans=trans,
C
chengjuntao 已提交
8066
                                                no_trans=False,
8067
                                                spatial_scale=1.0,
C
chengjuntao 已提交
8068 8069 8070 8071
                                                group_size=(1, 1),
                                                pooled_height=8,
                                                pooled_width=8,
                                                part_size=(8, 8),
8072
                                                sample_per_part=4,
C
chengjuntao 已提交
8073 8074
                                                trans_std=0.1,
                                                position_sensitive=False)
C
cjt222 已提交
8075 8076
    """

8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088
    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'
    )
8089
    if part_size is not None:
8090 8091 8092
        check_type(
            part_size, 'part_size', (list, tuple), 'deformable_roi_pooling'
        )
8093

C
cjt222 已提交
8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109
    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')
8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125
    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 已提交
8126
    return output
8127 8128


8129
@deprecated(since="2.0.0", update_to="paddle.shard_index")
8130 8131
def shard_index(input, index_num, nshards, shard_id, ignore_value=-1):
    """
L
lilong12 已提交
8132 8133 8134 8135 8136 8137 8138 8139 8140
    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).
8141 8142
    ::

8143
        shard_size = (index_num + nshards - 1) // nshards
8144

L
lilong12 已提交
8145 8146 8147
    For each value `v` in `input`, we reset it to a new value according to the
    following formula:
    ::
8148

L
lilong12 已提交
8149 8150 8151 8152
        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`.
8153 8154

    Args:
L
lilong12 已提交
8155 8156
        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`.
8157 8158 8159
        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.
8160 8161

    Returns:
L
lilong12 已提交
8162
        Tensor.
8163 8164 8165 8166

    Examples:
        .. code-block:: python

8167 8168 8169 8170 8171 8172 8173 8174
            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]]
8175
    """
H
hong 已提交
8176
    if in_dygraph_mode():
8177 8178 8179
        return _C_ops.shard_index(
            input, index_num, nshards, shard_id, ignore_value
        )
H
hong 已提交
8180

B
Baibaifan 已提交
8181
    check_variable_and_dtype(input, 'input', ['int64', 'int32'], 'shard_index')
8182 8183 8184
    op_type = 'shard_index'
    helper = LayerHelper(op_type, **locals())
    if shard_id < 0 or shard_id >= nshards:
8185 8186 8187
        raise ValueError(
            'The shard_id(%d) should be in [0, %d)' % (shard_id, nshards)
        )
8188 8189

    out = helper.create_variable_for_type_inference(dtype=input.dtype)
8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201
    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,
    )
8202
    return out
H
huangjun12 已提交
8203 8204 8205 8206


@templatedoc()
def hard_swish(x, threshold=6.0, scale=6.0, offset=3.0, name=None):
8207
    r"""
8208 8209 8210
    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 已提交
8211

8212
    The formula is as follows:
H
huangjun12 已提交
8213

8214
    .. math::
H
huangjun12 已提交
8215

8216
        out = \\frac{x * (min(max(0, x+offset), threshold))}{scale}
H
huangjun12 已提交
8217

8218 8219 8220 8221 8222 8223 8224 8225 8226
    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
8227 8228
        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`

8229 8230
    Returns:
        Variable: The output tensor with the same shape and data type as input.
8231 8232


8233
    Examples:
8234

8235
    .. code-block:: python
8236

8237
        import paddle.fluid as fluid
8238
        import paddle
8239
        import numpy as np
8240
        paddle.enable_static()
8241

8242
        DATATYPE='float32'
8243

8244
        x_data = np.array([i for i in range(1,5)]).reshape([1,1,4]).astype(DATATYPE)
8245

8246 8247
        x = fluid.data(name="x", shape=[None,1,4], dtype=DATATYPE)
        y = fluid.layers.hard_swish(x)
8248

8249 8250 8251 8252 8253
        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 已提交
8254
    """
J
Jiabin Yang 已提交
8255
    if _non_static_mode():
8256 8257 8258
        return _legacy_C_ops.hard_swish(
            x, 'threshold', threshold, 'scale', scale, 'offset', offset
        )
8259

8260 8261 8262
    check_variable_and_dtype(
        x, 'x', ['float16', 'float32', 'float64'], 'hard_swish'
    )
8263

H
huangjun12 已提交
8264 8265
    helper = LayerHelper('hard_swish', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
8266 8267 8268 8269 8270 8271
    helper.append_op(
        type='hard_swish',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'threshold': threshold, 'scale': scale, 'offset': offset},
    )
H
huangjun12 已提交
8272
    return out
R
ruri 已提交
8273 8274


K
Kaipeng Deng 已提交
8275 8276
@templatedoc()
def mish(x, threshold=20, name=None):
8277
    r"""
K
Kaipeng Deng 已提交
8278 8279 8280 8281 8282 8283 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295 8296 8297 8298 8299 8300 8301 8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334
    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.]]
    """
8335
    if in_dygraph_mode():
8336
        return _C_ops.mish(x, threshold)
8337
    if _in_legacy_dygraph():
8338
        return _legacy_C_ops.mish(x, 'threshold', threshold)
8339

K
Kaipeng Deng 已提交
8340 8341
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'mish')
    check_type(threshold, 'threshold', (float, int), 'mish')
8342 8343 8344 8345 8346
    assert (
        threshold > 0
    ), "threshold of mish should be greater than 0, " "but got {}".format(
        threshold
    )
K
Kaipeng Deng 已提交
8347 8348 8349

    helper = LayerHelper('mish', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
8350 8351 8352 8353 8354 8355
    helper.append_op(
        type='mish',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'threshold': threshold},
    )
K
Kaipeng Deng 已提交
8356 8357 8358
    return out


G
Guo Sheng 已提交
8359
def gather_tree(ids, parents):
8360
    r"""
G
Guo Sheng 已提交
8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384
    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]]]

8385 8386
            Then:
                gather_tree(ids, parents)
G
Guo Sheng 已提交
8387 8388 8389 8390 8391 8392 8393 8394
                         = [[[2 2]
                             [1 6]]
                            [[3 3]
                             [6 1]]
                            [[0 1]
                             [9 0]]]

    Args:
L
liu zhengxi 已提交
8395
        ids(Tensor): A Tensor with shape :attr:`[length, batch_size, beam_size]`
G
Guo Sheng 已提交
8396 8397
            and data type :attr:`int32` or :attr:`int64`. It contains the selected
            ids of all time steps.
L
liu zhengxi 已提交
8398
        parents(Tensor): A Tensor with the same shape and data type as :attr:`ids`,
G
Guo Sheng 已提交
8399 8400 8401 8402
            It contains the parents corresponding to selected ids when searching
            among beams.

    Returns:
L
liu zhengxi 已提交
8403
            A Tensor with the same shape and data type as :attr:`ids`. \
G
Guo Sheng 已提交
8404 8405 8406 8407 8408 8409
            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 已提交
8410 8411 8412 8413 8414 8415 8416 8417
            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 已提交
8418 8419

    """
8420
    return paddle.nn.functional.gather_tree(ids, parents)
G
Guo Sheng 已提交
8421 8422


8423
@deprecated(since="2.0.0", update_to="paddle.uniform")
8424
@templatedoc()
8425 8426 8427
def uniform_random(
    shape, dtype='float32', min=-1.0, max=1.0, seed=0, name=None
):
8428
    """
8429 8430
    This OP returns a Tensor filled with random values sampled from a uniform
    distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.
8431 8432 8433

    Examples:
    ::
8434

8435 8436
        Input:
          shape = [1, 2]
8437

8438 8439 8440 8441
        Output:
          result=[[0.8505902, 0.8397286]]

    Args:
8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454
        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
8455 8456
            use a seed generated by the system. Note that if seed is not 0,
            this operator will always generate the same random numbers every
8457
            time. Default is 0.
8458 8459 8460
        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`.
8461

8462
    Returns:
8463 8464
        Tensor: A Tensor filled with random values sampled from a uniform
        distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.
8465

8466
    Raises:
8467 8468
        TypeError: If ``shape`` is not list, tuple, Tensor.
        TypeError: If ``dtype`` is not float32, float64.
8469

8470 8471 8472
    Examples:
        .. code-block:: python

8473
            import paddle
8474
            import paddle.fluid as fluid
8475
            paddle.enable_static()
8476 8477

            # example 1:
8478
            # attr shape is a list which doesn't contain Tensor.
8479
            result_1 = fluid.layers.uniform_random(shape=[3, 4])
8480 8481 8482
            # [[ 0.84524226,  0.6921872,   0.56528175,  0.71690357],
            #  [-0.34646994, -0.45116323, -0.09902662, -0.11397249],
            #  [ 0.433519,    0.39483607, -0.8660099,   0.83664286]]
8483 8484

            # example 2:
8485 8486 8487
            # 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)
8488
            result_2 = fluid.layers.uniform_random(shape=[dim_1, dim_2])
8489 8490
            # [[-0.9951253,   0.30757582, 0.9899647 ],
            #  [ 0.5864527,   0.6607096,  -0.8886161 ]]
8491 8492

            # example 3:
8493
            # attr shape is a Tensor, the data type must be int64 or int32.
8494
            var_shape = fluid.data(name='var_shape', shape=[2], dtype="int64")
8495
            result_3 = fluid.layers.uniform_random(var_shape)
8496 8497 8498 8499
            # if var_shape's value is [2, 3]
            # result_3 is:
            # [[-0.8517412,  -0.4006908,   0.2551912 ],
            #  [ 0.3364414,   0.36278176, -0.16085452]]
8500

8501 8502 8503
    """
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
8504

8505 8506
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
8507
        return _C_ops.uniform(
8508 8509 8510 8511 8512 8513 8514
            shape,
            dtype,
            float(min),
            float(max),
            seed,
            _current_expected_place(),
        )
8515
    elif _in_legacy_dygraph():
8516
        shape = utils.convert_shape_to_list(shape)
8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528
        return _legacy_C_ops.uniform_random(
            'shape',
            shape,
            'min',
            float(min),
            'max',
            float(max),
            'seed',
            seed,
            'dtype',
            dtype,
        )
8529

8530
    check_type(shape, 'shape', (list, tuple, Variable), 'uniform_random/rand')
8531 8532 8533
    check_dtype(
        dtype, 'dtype', ('float32', 'float64', 'uint16'), 'uniform_random/rand'
    )
8534 8535
    check_type(min, 'min', (float, int, Variable), 'uniform_random/rand')
    check_type(max, 'max', (float, int, Variable), 'uniform_random/rand')
8536 8537

    inputs = dict()
8538
    attrs = {'seed': seed, 'min': min, 'max': max, 'dtype': dtype}
8539 8540 8541
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='uniform_random/rand'
    )
8542

8543
    helper = LayerHelper("uniform_random", **locals())
8544
    out = helper.create_variable_for_type_inference(dtype)
8545 8546 8547
    helper.append_op(
        type="uniform_random", inputs=inputs, attrs=attrs, outputs={"Out": out}
    )
8548
    utils.try_set_static_shape_tensor(out, shape)
8549
    return out
myq406450149's avatar
myq406450149 已提交
8550 8551 8552 8553 8554 8555 8556


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

myq406450149's avatar
myq406450149 已提交
8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582
        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()
8583 8584 8585
    check_dtype(
        dtype, 'unbind', ['float32', 'float64', 'int32', 'int64'], 'unbind'
    )
myq406450149's avatar
myq406450149 已提交
8586
    if not isinstance(axis, (int)):
8587 8588 8589
        raise TypeError(
            "The type of 'axis'  must be int, but received %s." % (type(axis))
        )
myq406450149's avatar
myq406450149 已提交
8590 8591 8592 8593 8594 8595 8596 8597 8598 8599
    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)
    ]

8600 8601 8602 8603 8604 8605
    helper.append_op(
        type="unbind",
        inputs={"X": input},
        outputs={"Out": outs},
        attrs={"axis": axis},
    )
myq406450149's avatar
myq406450149 已提交
8606
    return outs