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

import numpy as np

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

Y
Yu Yang 已提交
64 65

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

150
OP_NAMEMAPPING = {
151 152 153 154 155 156 157 158
    '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 已提交
159
    'elementwise_mod': 'remainder',
160 161
}

Y
Yu Yang 已提交
162

163 164
def _get_reduce_dim(dim, input):
    """
165
    Internal function for reduce_sum, reduce_mean, reduce_prod.
166 167 168 169 170 171 172 173 174
    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(
175 176 177 178
                "The type of dim must be int, list, tuple or range, but received {}".format(
                    type(axis)
                )
            )
179 180 181 182 183 184 185 186 187 188
    if dim is None:
        dim = []
    if dim == [] or len(dim) == len(input.shape):
        reduce_all = True
    else:
        reduce_all = False

    return reduce_all, dim


189
@dygraph_only
190 191 192
def _elementwise_op_in_dygraph(
    x, y, axis=-1, act=None, use_mkldnn=False, op_name=None
):
193 194 195 196
    def is_inplace(op_name):
        return op_name[-1] == "_"

    if op_name not in OP_NAMEMAPPING.keys() or axis != -1:
197
        op = getattr(_legacy_C_ops, op_name)
198 199 200
        out = op(x, y, 'axis', axis, 'use_mkldnn', use_mkldnn)
    else:
        if in_dygraph_mode():
201 202
            op = getattr(
                _C_ops,
203 204
                OP_NAMEMAPPING[op_name] if not is_inplace(op_name) else op_name,
            )
205 206 207
            out = op(x, y)

        if _in_legacy_dygraph():
208
            op = getattr(_legacy_C_ops, op_name)
209
            out = op(x, y, 'axis', axis, 'use_mkldnn', use_mkldnn)
210 211 212 213 214 215 216 217 218 219 220 221 222 223
    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,
):
224
    r"""
225 226
    :api_attr: Static Graph

227
    **Fully Connected Layer**
Y
Yu Yang 已提交
228

229 230 231
    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,
232
    which represents a fully connected weight matrix from each input unit to
233 234 235 236
    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`
237
    is not None, a bias variable will be created and added to the output.
238
    Finally, if :attr:`act` is not None, it will be applied to the output as well.
C
caoying03 已提交
239

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

242 243 244 245
    .. math::

        Out = Act({XW + b})

246
    When the input is a list of Tensor(or LoDTensor):
247 248 249

    .. math::

250
        Out = Act({\sum_{i=0}^{N-1}X_iW_i + b})
251 252 253

    In the above equation:

254 255 256
    * :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 已提交
257
    * :math:`b`: The bias parameter created by this layer (if needed).
258
    * :math:`Act`: The activation function.
259
    * :math:`Out`: The output Tensor.
260 261 262

    .. code-block:: text

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

    Raises:
318
        ValueError: If dimensions of the input Tensor is less than 2.
319 320 321 322

    Examples:
        .. code-block:: python

323
          import paddle.fluid as fluid
324 325
          import paddle
          paddle.enable_static()
326
          # when input is single tensor
327
          data = fluid.data(name="data", shape=[-1, 32], dtype="float32")
328
          fc = fluid.layers.fc(input=data, size=1000, act="tanh")
329 330

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

353 354 355
        w = helper.create_parameter(
            attr=param_attr, shape=param_shape, dtype=dtype, is_bias=False
        )
X
Xin Pan 已提交
356
        tmp = helper.create_variable_for_type_inference(dtype)
357 358 359 360 361 362
        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},
        )
363 364 365 366
        mul_results.append(tmp)

    if len(mul_results) == 1:
        pre_bias = mul_results[0]
367
    else:
X
Xin Pan 已提交
368
        pre_bias = helper.create_variable_for_type_inference(dtype)
369 370 371 372 373 374
        helper.append_op(
            type="sum",
            inputs={"X": mul_results},
            outputs={"Out": pre_bias},
            attrs={"use_mkldnn": False},
        )
375 376 377 378
    # 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 已提交
379 380


T
tangwei12 已提交
381
@deprecated(since="2.0.0", update_to="paddle.nn.functional.embedding")
382 383 384 385 386 387 388 389 390
def embedding(
    input,
    size,
    is_sparse=False,
    is_distributed=False,
    padding_idx=None,
    param_attr=None,
    dtype='float32',
):
391
    r"""
392
    :api_attr: Static Graph
393

394 395 396 397 398 399 400 401 402 403 404 405
    **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.

406
    **Note:** The id in :attr:`input` must satisfy :math:`0 =< id < size[0]` ,
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
    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]],
424

425 426 427 428
                        [[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.
429

430
        Case 2:
431

432 433 434 435 436 437 438 439 440 441 442 443 444 445
        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 已提交
446 447

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

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

479 480
    Examples:
        .. code-block:: python
Y
Yu Yang 已提交
481

B
bdzhuxiaoning 已提交
482
          import paddle.fluid as fluid
483
          import numpy as np
484 485
          import paddle
          paddle.enable_static()
486

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

T
tianshuo78520a 已提交
489
          # example 1
490 491 492 493 494 495 496 497 498
          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)
499
          emb_2 = fluid.layers.embedding(input=data, size=(128, 100), param_attr=w_param_attrs, dtype='float32')
Y
Yu Yang 已提交
500 501 502
    """

    helper = LayerHelper('embedding', **locals())
503 504 505 506 507 508 509 510 511
    check_variable_and_dtype(
        input, 'input', ['int64'], 'fluid.layers.embedding'
    )
    check_dtype(
        dtype,
        'dtype',
        ['uint16', 'float16', 'float32', 'float64'],
        'fluid.layers.embedding',
    )
512 513 514 515 516 517 518 519 520

    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

521 522 523
    w = helper.create_parameter(
        attr=helper.param_attr, shape=size, dtype=dtype, is_bias=False
    )
X
Xin Pan 已提交
524
    tmp = helper.create_variable_for_type_inference(dtype)
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
    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 已提交
543 544 545
    return tmp


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


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


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


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


Y
yuyang18 已提交
816
@templatedoc()
817
def linear_chain_crf(input, label, param_attr=None, length=None):
Y
yuyang18 已提交
818
    """
819 820
    :api_attr: Static Graph

Y
yuyang18 已提交
821 822 823 824 825
    Linear Chain CRF.

    ${comment}

    Args:
826
        input(${emission_type}): ${emission_comment}
Y
yuyang18 已提交
827
        label(${label_type}): ${label_comment}
828
        Length(${length_type}): ${length_comment}
829
        param_attr(ParamAttr): The attribute of the learnable parameter for transition parameter.
Y
yuyang18 已提交
830 831

    Returns:
D
dzhwinter 已提交
832 833
        output(${emission_exps_type}): ${emission_exps_comment} \n
        output(${transition_exps_type}): ${transition_exps_comment} \n
834
        output(${log_likelihood_type}): ${log_likelihood_comment} \n
Y
yuyang18 已提交
835

J
JesseyXujin 已提交
836 837 838
    Examples:
        .. code-block:: python

839 840
            import paddle.fluid as fluid
            import numpy as np
841 842
            import paddle
            paddle.enable_static()
843 844 845 846 847

            #define net structure, using LodTensor
            train_program = fluid.Program()
            startup_program = fluid.Program()
            with fluid.program_guard(train_program, startup_program):
848 849
                input_data = fluid.data(name='input_data', shape=[-1,10], dtype='float32')
                label = fluid.data(name='label', shape=[-1,1], dtype='int')
850 851 852 853 854 855
                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',
856
                    learning_rate=0.01))
857 858 859
            use_cuda = False
            place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
            exe = fluid.Executor(place)
860
            exe.run(startup_program)
861 862 863 864 865
            #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])
866
            print(loss)
867 868 869 870 871

            #define net structure, using padding
            train_program = fluid.Program()
            startup_program = fluid.Program()
            with fluid.program_guard(train_program, startup_program):
872 873 874
                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')
875 876 877 878 879 880
                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 已提交
881
                     name='crfw',
882 883 884 885 886 887
                     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 已提交
888

889 890 891
            #define data, using padding
            cc=np.random.rand(4,10,10).astype('float32')
            dd=np.random.rand(4,10,1).astype('int64')
892
            ll=np.array([[3],[3],[4],[2]])
893 894
            feed2 = {'input_data2':cc,'label2':dd,'length':ll}
            loss2= exe.run(train_program,feed=feed2, fetch_list=[crf_cost2])
895
            print(loss2)
896 897 898 899 900
            #[array([[ 7.8902354],
            #        [ 7.3602567],
            #        [ 10.004011],
            #        [ 5.86721  ]], dtype=float32)]

901 902 903
            #you can use find_var to get transition parameter.
            transition=np.array(fluid.global_scope().find_var('crfw').get_tensor())
            print(transition)
904

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

    return log_likelihood


W
wopeizl 已提交
950
@templatedoc()
951
def crf_decoding(input, param_attr, label=None, length=None):
W
wopeizl 已提交
952
    """
953
    :api_attr: Static Graph
954

W
wopeizl 已提交
955
    ${comment}
Y
yi.wu 已提交
956

W
wopeizl 已提交
957
    Args:
958
        input(Tensor): ${emission_comment}
Y
yi.wu 已提交
959

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

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

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

W
wopeizl 已提交
968
    Returns:
969
        Tensor: ${viterbi_path_comment}
Y
yi.wu 已提交
970

W
wopeizl 已提交
971 972
    Examples:
        .. code-block:: python
Y
yi.wu 已提交
973

974 975
           import paddle
           paddle.enable_static()
976 977 978

           # LoDTensor-based example
           num_labels = 10
979 980 981
           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)
982

983 984 985 986
           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"))
987 988 989

           # Common tensor example
           num_labels, max_len = 10, 20
990 991 992 993
           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,
994
                                      num_flatten_dims=2)
995

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

W
wopeizl 已提交
1018
    return viterbi_path
Y
Yu Yang 已提交
1019 1020


Y
yi.wu 已提交
1021
@templatedoc()
F
fengjiayi 已提交
1022
def cos_sim(X, Y):
Y
Yu Yang 已提交
1023
    """
Y
yi.wu 已提交
1024 1025 1026
    ${comment}

    Args:
N
Noel 已提交
1027 1028
        X (Tensor): ${x_comment}.
        Y (Tensor): ${y_comment}.
F
fengjiayi 已提交
1029

Y
yi.wu 已提交
1030
    Returns:
N
Noel 已提交
1031
        A Tensor representing the output of cosine(X, Y).
L
lvmengsi 已提交
1032 1033 1034 1035

    Examples:
        .. code-block:: python

N
Noel 已提交
1036 1037 1038 1039 1040 1041 1042
            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 已提交
1043
    """
1044 1045
    check_variable_and_dtype(X, 'X', ['float32'], 'cos_sim')
    check_variable_and_dtype(Y, 'Y', ['float32'], 'cos_sim')
F
fengjiayi 已提交
1046
    helper = LayerHelper('cos_sim', **locals())
X
Xin Pan 已提交
1047 1048 1049
    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)
1050 1051 1052 1053 1054
    helper.append_op(
        type='cos_sim',
        inputs={'X': [X], 'Y': [Y]},
        outputs={'Out': [out], 'XNorm': [xnorm], 'YNorm': [ynorm]},
    )
Y
Yu Yang 已提交
1055 1056 1057
    return out


1058
@deprecated(since="2.0.0", update_to="paddle.nn.functional.dropout")
1059 1060 1061 1062 1063 1064 1065 1066
def dropout(
    x,
    dropout_prob,
    is_test=None,
    seed=None,
    name=None,
    dropout_implementation="downgrade_in_infer",
):
1067
    """
1068

1069 1070 1071 1072
    Computes dropout.

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

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

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

P
phlrain 已提交
1092
                                        1. downgrade_in_infer(default), downgrade the outcome at inference
H
haowang101779990 已提交
1093 1094

                                           - train: out = input * mask
C
ceci3 已提交
1095
                                           - inference: out = input * (1.0 - dropout_prob)
H
haowang101779990 已提交
1096 1097 1098

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

H
haowang101779990 已提交
1101 1102
                                           - train: out = input * mask / ( 1.0 - dropout_prob )
                                           - inference: out = input
P
phlrain 已提交
1103

H
haowang101779990 已提交
1104 1105
                                           (mask is a tensor same shape with input, value is 0 or 1
                                           ratio of 0 is dropout_prob)
1106

M
minqiyang 已提交
1107

1108
    Returns:
L
lvmengsi 已提交
1109
        A Variable holding Tensor representing the dropout, has same shape and data type with `x`.
1110 1111

    Examples:
1112

1113 1114
        .. code-block:: python

1115
            import paddle
1116
            import paddle.fluid as fluid
1117

1118
            paddle.enable_static()
L
lvmengsi 已提交
1119
            x = fluid.data(name="data", shape=[None, 32, 32], dtype="float32")
T
tianshuo78520a 已提交
1120
            dropped = fluid.layers.dropout(x, dropout_prob=0.5)
1121
    """
1122 1123
    if not isinstance(dropout_prob, (float, int, Variable)):
        raise TypeError(
1124 1125
            "dropout_prob argument should be a number(int|float) or Variable"
        )
1126
    # fast return for p == 0
1127
    if isinstance(dropout_prob, (int, float)) and dropout_prob == 0:
1128
        return x
1129

J
Jiabin Yang 已提交
1130
    if _non_static_mode():
1131 1132 1133
        if (
            seed is None or seed == 0
        ) and default_main_program().random_seed != 0:
1134
            seed = default_main_program().random_seed
1135 1136
        if is_test is None:
            is_test = not _dygraph_tracer()._train_mode
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149
        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,
        )
1150
        return out
1151

W
wanghuancoder 已提交
1152 1153 1154
    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
1155 1156
        if isinstance(dropout_prob, Variable) and not dropout_prob.shape != [1]:
            raise TypeError(
1157 1158 1159 1160
                "Required dropout_prob.shape == [1] if type(dropout_prob) is Variable, but received dropout_prob.shape = {}".format(
                    dropout_prob.shape
                )
            )
W
wanghuancoder 已提交
1161 1162 1163 1164 1165 1166 1167 1168 1169
        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 已提交
1170
    helper = LayerHelper('dropout', **locals())
1171 1172 1173
    check_variable_and_dtype(
        x, 'x', ['float16', 'float32', 'float64'], 'dropout'
    )
1174

X
Xin Pan 已提交
1175 1176
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
    mask = helper.create_variable_for_type_inference(
1177 1178
        dtype=core.VarDesc.VarType.UINT8, stop_gradient=True
    )
C
chengduo 已提交
1179

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

1182 1183 1184 1185 1186 1187
    helper.append_op(
        type='dropout',
        inputs={'X': [x]},
        outputs={'Out': [out], 'Mask': [mask]},
        attrs=attrs,
    )
1188 1189 1190
    return out


1191
@deprecated(since="2.0.0", update_to="paddle.nn.functional.softmax")
1192
def softmax(input, use_cudnn=True, name=None, axis=-1):
1193
    r"""
1194
    This operator implements the softmax layer. The calculation process is as follows:
1195

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

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

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

1209 1210 1211 1212 1213
    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.
1214

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

1217
    .. math::
1218

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

1221
    Example:
1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265

    .. 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],
1266
                         [0.72747516, 0.72747516, 0.72747516, 0.72747516]]]
1267

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

    Returns:
N
Noel 已提交
1279
        Tensor: ``Tensor`` indicates the output of softmax. The data type and shape are the same as ``input`` .
Q
qiaolongfei 已提交
1280 1281 1282 1283 1284

    Examples:

        .. code-block:: python

N
Noel 已提交
1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301
            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 已提交
1302 1303

    """
1304

H
hong 已提交
1305
    if in_dygraph_mode():
1306
        return _C_ops.softmax(input, axis)
H
hong 已提交
1307

J
Jiabin Yang 已提交
1308
    if _non_static_mode():
1309 1310 1311
        return _legacy_C_ops.softmax(
            input, 'axis', axis, 'use_cudnn', use_cudnn
        )
1312 1313 1314

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

1316
    helper = LayerHelper('softmax', **locals())
1317 1318 1319
    check_variable_and_dtype(
        input, 'input/x', ['float16', 'float32', 'float64'], 'softmax'
    )
1320

1321
    dtype = helper.input_dtype()
X
Xin Pan 已提交
1322
    softmax_out = helper.create_variable_for_type_inference(dtype)
1323 1324 1325 1326 1327 1328
    helper.append_op(
        type="softmax",
        inputs={"X": input},
        outputs={"Out": softmax_out},
        attrs=attrs,
    )
1329 1330 1331
    return softmax_out


1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346
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",
):
1347
    r"""
1348 1349
    :api_attr: Static Graph

C
chengduoZH 已提交
1350
    The convolution2D layer calculates the output based on the input, filter
T
tensor-tang 已提交
1351
    and strides, paddings, dilations, groups parameters. Input and
L
liym27 已提交
1352
    Output are in NCHW or NHWC format, where N is batch size, C is the number of
1353
    channels, H is the height of the feature, and W is the width of the feature.
T
tensor-tang 已提交
1354 1355 1356 1357 1358 1359
    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/>`_
1360
    for more details.
1361 1362 1363
    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 已提交
1364

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

C
chengduoZH 已提交
1367 1368
    .. math::

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

T
tensor-tang 已提交
1371
    Where:
C
chengduoZH 已提交
1372

L
liym27 已提交
1373
    * :math:`X`: Input value, a tensor with NCHW or NHWC format.
1374 1375 1376 1377
    * :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 已提交
1378
    * :math:`Out`: Output value, the shape of :math:`Out` and :math:`X` may be different.
C
chengduoZH 已提交
1379 1380 1381

    Example:

1382 1383
        - Input:

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

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

1388
        - Output:
T
tensor-tang 已提交
1389

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

C
chengduoZH 已提交
1392
        Where
1393 1394

        .. math::
C
chengduoZH 已提交
1395

W
weixing02 已提交
1396 1397
            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 已提交
1398 1399

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

    Returns:
1453 1454 1455
        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 已提交
1456
        and non-linearity activation result.
C
refine  
chengduoZH 已提交
1457

1458 1459 1460 1461 1462
    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".
1463
        ValueError: If `padding` is a tuple, but the element corresponding to the input's batch size is not 0
1464 1465 1466 1467 1468 1469 1470
            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 已提交
1471 1472 1473
    Examples:
        .. code-block:: python

1474 1475
          import paddle
          paddle.enable_static()
1476

1477 1478 1479
          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 已提交
1480 1481
    """

1482 1483 1484
    check_variable_and_dtype(
        input, 'input', ['float16', 'float32', 'float64'], 'conv2d'
    )
1485
    if len(input.shape) != 4:
1486 1487 1488 1489
        raise ValueError(
            "Input size should be 4, "
            "but received {}".format(len(input.shape))
        )
1490
    num_channels = input.shape[1]
L
liym27 已提交
1491
    if not isinstance(use_cudnn, bool):
1492 1493 1494 1495
        raise ValueError(
            "Attr(use_cudnn) should be True or False. Received "
            "Attr(use_cudnn): %s. " % str(use_cudnn)
        )
L
liym27 已提交
1496 1497 1498 1499

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

1503
    channel_last = data_format == "NHWC"
L
liym27 已提交
1504 1505 1506 1507
    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. "
1508 1509
            "Received: %s." % (str(input.shape), str(num_channels))
        )
C
chengduo 已提交
1510
    assert param_attr is not False, "param_attr should not be False here."
L
liym27 已提交
1511

1512 1513 1514
    if groups is None:
        num_filter_channels = num_channels
    elif groups <= 0:
1515 1516
        raise ValueError(
            "the groups of input must be greater than 0, "
1517 1518
            "but received the groups of input is {}".format(groups)
        )
1519 1520 1521 1522 1523
    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 {}"
1524 1525
                ", the groups is {}".format(num_channels, input.shape, groups)
            )
1526 1527
        num_filter_channels = num_channels // groups

1528
    l_type = 'conv2d'
1529 1530 1531 1532 1533
    if (
        num_channels == groups
        and num_filters % num_channels == 0
        and not use_cudnn
    ):
1534
        l_type = 'depthwise_conv2d'
1535

1536 1537 1538 1539 1540
    if (
        num_channels == groups
        and num_filters % num_channels == 0
        and core.is_compiled_with_rocm()
    ):
1541 1542
        l_type = 'depthwise_conv2d'

1543 1544
    # NPU only supports depthwise_conv2d when  "input_channel = output_channel = groups"
    if core.is_compiled_with_npu():
1545
        if num_channels == groups and num_channels == num_filters:
1546 1547 1548 1549
            l_type = 'depthwise_conv2d'
        else:
            l_type = 'conv2d'

1550 1551 1552
    helper = LayerHelper(l_type, **locals())
    dtype = helper.input_dtype()

C
chengduoZH 已提交
1553 1554
    filter_size = utils.convert_to_list(filter_size, 2, 'filter_size')
    stride = utils.convert_to_list(stride, 2, 'stride')
1555
    dilation = utils.convert_to_list(dilation, 2, 'dilation')
C
chengduoZH 已提交
1556

L
liym27 已提交
1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568
    # 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 "
1569 1570
                        "is not supported." % str(padding)
                    )
L
liym27 已提交
1571 1572 1573 1574 1575 1576
                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 "
1577 1578
                        "is not supported." % str(padding)
                    )
L
liym27 已提交
1579 1580 1581
                padding = padding[1:3]
                padding = [ele for a_list in padding for ele in a_list]
            padding = utils.convert_to_list(padding, 4, 'padding')
1582 1583 1584
            if utils._is_symmetric_padding(padding, 2):
                padding = [padding[0], padding[2]]

L
liym27 已提交
1585 1586 1587 1588 1589 1590 1591 1592 1593 1594
        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(
1595 1596 1597
                "Unknown padding: '%s'. It can only be 'SAME' or 'VALID'."
                % str(padding)
            )
L
liym27 已提交
1598 1599
        if padding == "VALID":
            padding_algorithm = "VALID"
1600
            padding = [0, 0]
L
liym27 已提交
1601 1602
        elif padding == "SAME":
            padding_algorithm = "SAME"
1603
            padding = [0, 0]
L
liym27 已提交
1604 1605

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

M
minqiyang 已提交
1607
    filter_shape = [num_filters, int(num_filter_channels)] + filter_size
Y
Yu Yang 已提交
1608 1609

    def _get_default_param_initializer():
C
chengduo 已提交
1610
        filter_elem_num = filter_size[0] * filter_size[1] * num_channels
1611 1612 1613 1614
        if filter_elem_num <= 0:
            raise ValueError(
                "Invalid filter number, excepted number is larger than 0, but"
                " received {}, please check the input shape and "
1615 1616 1617
                "filter size.".format(filter_elem_num)
            )
        std = (2.0 / filter_elem_num) ** 0.5
Y
Yu Yang 已提交
1618 1619 1620 1621 1622 1623
        return Normal(0.0, std, 0)

    filter_param = helper.create_parameter(
        attr=helper.param_attr,
        shape=filter_shape,
        dtype=dtype,
1624 1625
        default_initializer=_get_default_param_initializer(),
    )
Y
Yu Yang 已提交
1626

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

1629 1630 1631 1632 1633 1634
    if (
        core.is_compiled_with_cuda()
        and paddle.fluid.get_flags("FLAGS_conv2d_disable_cudnn")[
            "FLAGS_conv2d_disable_cudnn"
        ]
    ):
1635 1636
        use_cudnn = False

1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655
    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 已提交
1656

1657 1658 1659 1660
    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 已提交
1661 1662 1663 1664

    return helper.append_activation(pre_act)


F
fengjiayi 已提交
1665
@templatedoc()
1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678
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 已提交
1679
    """
1680

F
fengjiayi 已提交
1681
    ${comment}
1682 1683

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

1716
    Returns:
K
Kaipeng Deng 已提交
1717
        Variable: The output tensor of pooling result. The data type is same as input tensor.
F
fengjiayi 已提交
1718 1719

    Raises:
1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731
        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 已提交
1732 1733 1734 1735 1736

    Examples:

        .. code-block:: python

1737
          import paddle.fluid as fluid
1738 1739 1740
          import paddle

          paddle.enable_static()
1741

K
Kaipeng Deng 已提交
1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766
          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)
1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784

          # 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 已提交
1785 1786 1787
    """
    if pool_type not in ["max", "avg"]:
        raise ValueError(
1788
            "Unknown Attr(pool_type): '%s'. It can only be 'max' or 'avg'.",
1789 1790
            str(pool_type),
        )
C
chengduoZH 已提交
1791

C
chengduoZH 已提交
1792 1793
    if global_pooling is False and pool_size == -1:
        raise ValueError(
1794
            "When Attr(global_pooling) is False, Attr(pool_size) must be passed "
1795 1796
            "and be a valid value. Received pool_size: %s." % str(pool_size)
        )
1797 1798

    if not isinstance(use_cudnn, bool):
1799 1800 1801 1802
        raise TypeError(
            "Attr(use_cudnn) should be True or False. Received "
            "Attr(use_cudnn): %s." % str(use_cudnn)
        )
1803 1804 1805 1806

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

C
chengduoZH 已提交
1810 1811 1812
    pool_size = utils.convert_to_list(pool_size, 2, 'pool_size')
    pool_stride = utils.convert_to_list(pool_stride, 2, 'pool_stride')

1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823
    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 "
1824 1825
                        "is not supported." % str(padding)
                    )
1826 1827 1828 1829 1830 1831
                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 "
1832 1833
                        "is not supported." % str(padding)
                    )
1834 1835 1836
                padding = padding[1:3]
                padding = [ele for a_list in padding for ele in a_list]
            padding = utils.convert_to_list(padding, 4, 'padding')
1837

1838 1839
            if utils._is_symmetric_padding(padding, 2):
                padding = [padding[0], padding[2]]
1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850
        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'."
1851 1852
                % str(pool_padding)
            )
1853 1854
        if pool_padding == "VALID":
            padding_algorithm = "VALID"
1855
            pool_padding = [0, 0]
1856 1857 1858
            if ceil_mode != False:
                raise ValueError(
                    "When Attr(pool_padding) is \"VALID\", Attr(ceil_mode) must be False. "
1859 1860
                    "Received ceil_mode: True."
                )
1861 1862
        elif pool_padding == "SAME":
            padding_algorithm = "SAME"
1863
            pool_padding = [0, 0]
1864 1865

    pool_padding = update_padding(pool_padding, data_format)
1866
    if in_dygraph_mode():
1867
        input = input._use_cudnn(use_cudnn)
1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880
        return _C_ops.pool2d(
            input,
            pool_size,
            pool_stride,
            pool_padding,
            ceil_mode,
            exclusive,
            data_format,
            pool_type,
            global_pooling,
            False,
            padding_algorithm,
        )
1881 1882
    op_type = 'pool2d'
    helper = LayerHelper(op_type, **locals())
Y
Yu Yang 已提交
1883
    dtype = helper.input_dtype()
X
Xin Pan 已提交
1884
    pool_out = helper.create_variable_for_type_inference(dtype)
Y
Yu Yang 已提交
1885

1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903
    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,
        },
    )
1904 1905 1906 1907

    return pool_out


D
dengkaipeng 已提交
1908
@templatedoc()
1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921
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",
):
1922
    """
1923

1924
    ${comment}
1925 1926

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

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

1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976
    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 已提交
1977 1978 1979 1980
    Examples:

        .. code-block:: python

1981
          import paddle.fluid as fluid
1982 1983 1984
          import paddle

          paddle.enable_static()
1985

K
Kaipeng Deng 已提交
1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010
          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)
2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033

          # 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 已提交
2034 2035 2036
    """
    if pool_type not in ["max", "avg"]:
        raise ValueError(
2037
            "Unknown Attr(pool_type): '%s'. It can only be 'max' or 'avg'.",
2038 2039
            str(pool_type),
        )
C
chengduoZH 已提交
2040

C
chengduoZH 已提交
2041 2042
    if global_pooling is False and pool_size == -1:
        raise ValueError(
2043
            "When Attr(global_pooling) is False, Attr(pool_size) must be passed "
2044 2045 2046
            "and be a valid value. Received Attr(pool_size): %s."
            % str(pool_size)
        )
2047 2048

    if not isinstance(use_cudnn, bool):
2049 2050 2051 2052
        raise TypeError(
            "Attr(use_cudnn) should be True or False. Received "
            "Attr(use_cudnn): %s. " % str(use_cudnn)
        )
2053 2054 2055 2056

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

2060 2061
    pool_size = utils.convert_to_list(pool_size, 3, 'pool_size')
    pool_stride = utils.convert_to_list(pool_stride, 3, 'pool_stride')
C
chengduoZH 已提交
2062

2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073
    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 "
2074 2075
                        "is not supported." % str(padding)
                    )
2076 2077 2078 2079 2080 2081
                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 "
2082 2083
                        "is not supported." % str(padding)
                    )
2084 2085 2086
                padding = padding[1:4]
                padding = [ele for a_list in padding for ele in a_list]
            padding = utils.convert_to_list(padding, 6, 'padding')
2087 2088
            if utils._is_symmetric_padding(padding, 3):
                padding = [padding[0], padding[2], padding[4]]
2089 2090 2091

        elif is_list_or_tuple(padding) and len(padding) == 6:
            padding = utils.convert_to_list(padding, 6, 'padding')
2092 2093
            if utils._is_symmetric_padding(padding, 3):
                padding = [padding[0], padding[2], padding[4]]
2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104
        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'."
2105 2106
                % str(pool_padding)
            )
2107 2108
        if pool_padding == "VALID":
            padding_algorithm = "VALID"
2109
            pool_padding = [0, 0, 0]
2110 2111 2112
            if ceil_mode != False:
                raise ValueError(
                    "When Attr(pool_padding) is \"VALID\", ceil_mode must be False. "
2113 2114
                    "Received ceil_mode: True."
                )
2115 2116
        elif pool_padding == "SAME":
            padding_algorithm = "SAME"
2117
            pool_padding = [0, 0, 0]
2118 2119 2120 2121 2122

    pool_padding = update_padding(pool_padding, data_format)

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

2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143
    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 已提交
2144 2145 2146 2147

    return pool_out


2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163
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,
):
2164
    r"""
2165 2166
    :api_attr: Static Graph

Q
qiaolongfei 已提交
2167 2168
    **Batch Normalization Layer**

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

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

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

Q
qiaolongfei 已提交
2176 2177 2178
    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 已提交
2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190

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

L
lvmengsi 已提交
2192
        moving\_mean = moving\_mean * momentum + mini-batch\_mean * (1. - momentum) \\\\
2193
        moving\_var = moving\_var * momentum + mini-batch\_var * (1. - momentum)
L
lvmengsi 已提交
2194

2195

L
lvmengsi 已提交
2196
    moving_mean is global mean and moving_var is global variance.
2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209

    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 已提交
2210
    Note:
2211
        if build_strategy.sync_batch_norm=True, the batch_norm in network will use
L
lvmengsi 已提交
2212
        sync_batch_norm automatically.
2213
        `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 已提交
2214

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

    Examples:

        .. code-block:: python

2267
            import paddle
2268

2269
            paddle.enable_static()
2270 2271 2272 2273 2274 2275 2276
            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 已提交
2277
    """
2278 2279 2280
    assert (
        bias_attr is not False
    ), "bias_attr should not be False in batch_norm."
Y
Yu Yang 已提交
2281 2282
    helper = LayerHelper('batch_norm', **locals())

2283 2284 2285
    check_variable_and_dtype(
        input, 'input', ['float16', 'float32', 'float64'], 'batch_norm'
    )
2286
    dtype = helper.input_dtype()
2287

W
Wu Yi 已提交
2288 2289 2290 2291
    # use fp32 for bn parameter
    if dtype == core.VarDesc.VarType.FP16:
        dtype = core.VarDesc.VarType.FP32

Y
Yu Yang 已提交
2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303
    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
2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323
    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,
    )
2324 2325
    mean.stop_gradient = True

2326 2327 2328 2329 2330 2331 2332 2333 2334 2335
    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,
    )
2336
    variance.stop_gradient = True
Y
Yu Yang 已提交
2337 2338 2339 2340

    # create output
    # mean and mean_out share the same memory
    mean_out = mean
2341
    # variance and variance_out share the same memory
Y
Yu Yang 已提交
2342
    variance_out = variance
2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354

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

2411 2412 2413
        return dygraph_utils._append_activation_in_dygraph(
            batch_norm_out, act=act, use_mkldnn=False
        )
2414

2415 2416 2417
    saved_mean = helper.create_variable_for_type_inference(
        dtype=dtype, stop_gradient=True
    )
X
Xin Pan 已提交
2418
    saved_variance = helper.create_variable_for_type_inference(
2419 2420
        dtype=dtype, stop_gradient=True
    )
2421
    reserve_space = None
2422
    if not is_test:
2423
        reserve_space = helper.create_variable_for_type_inference(
2424 2425
            dtype=helper.input_dtype(), stop_gradient=True
        )
2426

2427 2428 2429
    batch_norm_out = (
        input if in_place else helper.create_variable_for_type_inference(dtype)
    )
Y
Yu Yang 已提交
2430

2431 2432 2433 2434 2435
    inputs = {
        "X": input,
        "Scale": scale,
        "Bias": bias,
        "Mean": mean,
2436 2437
        "Variance": variance,
        "MeanOut": mean_out,
2438
        "VarianceOut": variance_out,
2439 2440 2441 2442 2443 2444 2445
    }
    attrs = {
        "epsilon": epsilon,
        "is_test": is_test,
        "data_layout": data_layout,
        "use_mkldnn": False,
        "fuse_with_relu": False,
2446
        "use_global_stats": use_global_stats,
2447 2448 2449 2450 2451
    }
    if isinstance(momentum, Variable):
        inputs['MomemtumTensor'] = momentum
    else:
        attrs['momentum'] = momentum
2452 2453 2454 2455 2456 2457

    outputs = {
        "Y": batch_norm_out,
        "MeanOut": mean_out,
        "VarianceOut": variance_out,
        "SavedMean": saved_mean,
2458
        "SavedVariance": saved_variance,
2459 2460 2461 2462
    }
    if reserve_space is not None:
        outputs["ReserveSpace"] = reserve_space

2463 2464 2465
    helper.append_op(
        type="batch_norm", inputs=inputs, outputs=outputs, attrs=attrs
    )
Y
Yu Yang 已提交
2466 2467 2468 2469

    return helper.append_activation(batch_norm_out)


2470 2471 2472
def instance_norm(
    input, epsilon=1e-05, param_attr=None, bias_attr=None, name=None
):
2473
    r"""
2474 2475
    :api_attr: Static Graph

L
lvmengsi 已提交
2476 2477
    **Instance Normalization Layer**

L
lvmengsi 已提交
2478
    Can be used as a normalizer function for convolution or fully_connected operations.
L
lvmengsi 已提交
2479 2480 2481 2482
    The required data format for this layer is one of the following:

    DataLayout: NCHW `[batch, in_channels, in_height, in_width]`

2483
    Refer to `Instance Normalization: The Missing Ingredient for
L
lvmengsi 已提交
2484 2485 2486 2487 2488 2489 2490 2491
    Fast Stylization <https://arxiv.org/pdf/1607.08022.pdf>`_
    for more details.

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

    ..  math::

        \\mu_{\\beta} &\\gets \\frac{1}{HW} \\sum_{i=1}^{HW} x_i \\qquad &//\\
L
lvmengsi 已提交
2492
        \\ mean\ of\ one\  feature\ map\ in\ mini-batch \\\\
L
lvmengsi 已提交
2493
        \\sigma_{\\beta}^{2} &\\gets \\frac{1}{HW} \\sum_{i=1}^{HW}(x_i - \\
L
lvmengsi 已提交
2494
        \\mu_{\\beta})^2 \\qquad &//\ variance\ of\ one\ feature\ map\ in\ mini-batch \\\\
L
lvmengsi 已提交
2495 2496 2497 2498
        \\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

L
lvmengsi 已提交
2499 2500
    Note:
        `H` means height of feature map, `W` means width of feature map.
L
lvmengsi 已提交
2501 2502

    Args:
C
ceci3 已提交
2503
        input(Tensor): The rank of input tensor can be 2, 3, 4, 5.
L
lvmengsi 已提交
2504
            The data type is float32 or float64.
L
lvmengsi 已提交
2505 2506
        epsilon(float, Default 1e-05): A value added to the denominator for
            numerical stability. Default is 1e-5.
C
ceci3 已提交
2507
        param_attr(ParamAttr|None|bool, optional): The parameter attribute for Parameter `scale`
L
lvmengsi 已提交
2508 2509
             of instance_norm. If it is set to None or one attribute of ParamAttr, instance_norm
	     will create ParamAttr as param_attr, the name of scale can be set in ParamAttr.
2510
	     If the Initializer of the param_attr is not set, the parameter is initialized
C
ceci3 已提交
2511 2512 2513
	     with Xavier. If the param_attr is set to False, instance_norm will not create param_attr.
             Default: None.
        bias_attr(ParamAttr|None|bool, optional): The parameter attribute for the bias of instance_norm.
L
lvmengsi 已提交
2514
             If it is set to None or one attribute of ParamAttr, instance_norm
2515 2516
	     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.
C
ceci3 已提交
2517
             If the bias_attr is set to False, instance_norm will not create bias_attr.
L
lvmengsi 已提交
2518 2519 2520 2521 2522
	     Default: None.
        name(string, Default None): A name for this layer(optional). If set None, the layer
            will be named automatically.

    Returns:
C
ceci3 已提交
2523
        A Tensor which is the result after applying instance normalization on the input,
2524
        has same shape and data type with input.
L
lvmengsi 已提交
2525 2526 2527 2528 2529

    Examples:

        .. code-block:: python

2530 2531
            import paddle
            paddle.enable_static()
C
ceci3 已提交
2532 2533 2534
            x = paddle.static.data(name='x', shape=[3, 7, 3, 7], dtype='float32')
            hidden1 = paddle.static.nn.fc(x, size=200)
            hidden2 = paddle.static.nn.instance_norm(hidden1)
L
lvmengsi 已提交
2535
    """
2536 2537 2538
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'instance_norm'
    )
C
ceci3 已提交
2539
    if param_attr is False:
2540 2541
        assert (
            bias_attr is False
2542
        ), "param_attr and bias_attr must be set to False at the same time in instance_norm"
C
ceci3 已提交
2543

L
lvmengsi 已提交
2544 2545 2546 2547 2548 2549 2550 2551
    helper = LayerHelper('instance_norm', **locals())
    dtype = helper.input_dtype()

    # use fp32 for in parameter
    if dtype == core.VarDesc.VarType.FP16:
        dtype = core.VarDesc.VarType.FP32

    input_shape = input.shape
C
ceci3 已提交
2552 2553
    if len(input.shape) < 2 or len(input.shape) > 5:
        raise ValueError(
2554 2555 2556 2557
            'expected 2D or 3D or 4D or 5D input (got {}D input, input shape is: {})'.format(
                len(input.shape), input_shape
            )
        )
L
lvmengsi 已提交
2558 2559 2560 2561
    channel_num = input_shape[1]

    param_shape = [channel_num]

2562
    if param_attr != False and bias_attr != False:
C
ceci3 已提交
2563
        # create parameter
2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576
        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,
            default_initializer=Constant(0.0),
        )
L
lvmengsi 已提交
2577 2578

    # create output
2579 2580 2581
    saved_mean = helper.create_variable_for_type_inference(
        dtype=dtype, stop_gradient=True
    )
L
lvmengsi 已提交
2582
    saved_variance = helper.create_variable_for_type_inference(
2583 2584
        dtype=dtype, stop_gradient=True
    )
L
lvmengsi 已提交
2585 2586 2587

    instance_norm_out = helper.create_variable_for_type_inference(dtype)

C
ceci3 已提交
2588
    inputs = {"X": input}
2589
    if param_attr != False and bias_attr != False:
C
ceci3 已提交
2590 2591 2592
        inputs["Scale"] = scale
        inputs["Bias"] = bias

2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604
    helper.append_op(
        type="instance_norm",
        inputs=inputs,
        outputs={
            "Y": instance_norm_out,
            "SavedMean": saved_mean,
            "SavedVariance": saved_variance,
        },
        attrs={
            "epsilon": epsilon,
        },
    )
L
lvmengsi 已提交
2605 2606 2607 2608

    return instance_norm_out


2609
@static_only
2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625
def data_norm(
    input,
    act=None,
    epsilon=1e-05,
    param_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,
    slot_dim=-1,
    sync_stats=False,
    summary_decay_rate=0.9999999,
    enable_scale_and_shift=False,
):
2626
    r"""
2627 2628
    :api_attr: Static Graph

H
heqiaozhi 已提交
2629 2630
    **Data Normalization Layer**

2631
    This op can be used as a normalizer function for conv2d and fully_connected operations.
H
heqiaozhi 已提交
2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650
    The required data format for this layer is one of the following:

    1. NHWC `[batch, in_height, in_width, in_channels]`

    2. NCHW `[batch, in_channels, in_height, in_width]`

    :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

    Args:
Y
yaoxuefeng 已提交
2651
        input(Tensor): The input Tensor.
H
heqiaozhi 已提交
2652 2653 2654
        act(string, Default None): Activation type, linear|relu|prelu|...
        epsilon(float, Default 1e-05):
        param_attr(ParamAttr): The parameter attribute for Parameter `scale`.
2655
        data_layout (str, optional): Specify the data format of the input, and the data format of the output
2656 2657 2658
            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]`.
H
heqiaozhi 已提交
2659 2660 2661 2662 2663
        in_place(bool, Default False): Make the input and output of batch norm reuse memory.
        name(string, Default None): A name for this layer(optional). If set None, the layer
            will be named automatically.
        moving_mean_name(string, Default None): The name of moving_mean which store the global Mean.
        moving_variance_name(string, Default None): The name of the moving_variance which store the global Variance.
2664 2665
        do_model_average_for_mean_and_var(bool, Default True): Whether parameter mean and variance
            should do model average when model average is enabled.
2666
        slot_dim(int): The embedding dimension of one slot. Slot is a set of one specific feature. In pslib mode, we
2667 2668
            distinguish feature ids by slot and pull their embeddings from parameter server (pslib). The first
            place of the embedding is the historical show number (occurence time of this feature id with a label 0).
2669 2670
            If the input of this op is concated by slot-wise embeddings, and the show number is zero when this slot
            is new or empty, the normalization result may be impractical. To avoid this, we add slot_dim to locate
2671 2672
            the show number and judge if the show number is zero. If so, we choose to skip normalization on this
            embedding.
H
hutuxian 已提交
2673 2674 2675
        sync_stats(bool, Default False): When running with multiple GPU cards, using allreduce to sync the
            summary messages.
        summary_decay_rate(float, Default 0.9999999): The decay rate when updating summary.
2676
        enable_scale_and_shift(bool, Default False): do scale&shift after normalization.
H
heqiaozhi 已提交
2677 2678

    Returns:
Y
yaoxuefeng 已提交
2679
        Tensor: A tensor which is the result after applying data normalization on the input.
H
heqiaozhi 已提交
2680 2681 2682 2683

    Examples:

        .. code-block:: python
2684

Y
yaoxuefeng 已提交
2685
            import paddle
2686
            paddle.enable_static()
H
heqiaozhi 已提交
2687

Y
yaoxuefeng 已提交
2688 2689
            x = paddle.randn(shape=[32,100])
            hidden2 = paddle.static.nn.data_norm(input=x)
H
heqiaozhi 已提交
2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707
    """
    helper = LayerHelper('data_norm', **locals())
    dtype = helper.input_dtype()

    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]

    batch_size_default = 1e4
    batch_sum_default = 0.0
    batch_square_sum_default = 1e4
2708 2709
    scale_w_default = 1.0
    bias_default = 0.0
H
heqiaozhi 已提交
2710 2711 2712 2713 2714

    if param_attr and isinstance(param_attr, dict):
        batch_size_default = param_attr.get("batch_size", 1e4)
        batch_sum_default = param_attr.get("batch_sum", 0.0)
        batch_square_sum_default = param_attr.get("batch_square", 1e4)
2715 2716 2717 2718 2719
    if enable_scale_and_shift:
        scale_w_default = param_attr.get("scale_w", 1.0)
        bias_default = param_attr.get("bias", 0.0)

    # create scale and shift(bias) when enable_scale_and_shift is True
2720
    if name is None:
2721 2722
        name = "dn"
    if enable_scale_and_shift:
2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740
        scale_w = helper.create_parameter(
            attr=ParamAttr(
                name=name + '.scale_w',
                initializer=Constant(value=float(scale_w_default)),
                trainable=True,
            ),
            shape=param_shape,
            dtype=input.dtype,
        )
        bias = helper.create_parameter(
            attr=ParamAttr(
                name=name + '.bias',
                initializer=Constant(value=float(bias_default)),
                trainable=True,
            ),
            shape=param_shape,
            dtype=input.dtype,
        )
2741
    # create parameter
2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770
    batch_size = helper.create_parameter(
        attr=ParamAttr(
            name=name + '.batch_size',
            initializer=Constant(value=float(batch_size_default)),
            trainable=True,
        ),
        shape=param_shape,
        dtype=input.dtype,
    )

    batch_sum = helper.create_parameter(
        attr=ParamAttr(
            name=name + '.batch_sum',
            initializer=Constant(value=float(batch_sum_default)),
            trainable=True,
        ),
        shape=param_shape,
        dtype=input.dtype,
    )

    batch_square_sum = helper.create_parameter(
        attr=ParamAttr(
            name=name + '.batch_square_sum',
            initializer=Constant(value=float(batch_square_sum_default)),
            trainable=True,
        ),
        shape=param_shape,
        dtype=input.dtype,
    )
H
heqiaozhi 已提交
2771 2772 2773 2774 2775 2776

    means = helper.create_variable(dtype=dtype, stop_gradient=True)
    scales = helper.create_variable(dtype=dtype, stop_gradient=True)

    data_norm_out = input if in_place else helper.create_variable(dtype=dtype)

2777 2778 2779 2780
    inputs = {
        "X": input,
        "BatchSize": batch_size,
        "BatchSum": batch_sum,
2781
        "BatchSquareSum": batch_square_sum,
2782
    }
2783 2784
    attrs = {
        "epsilon": epsilon,
X
XiangGao 已提交
2785
        "data_layout": data_layout,
2786 2787 2788 2789 2790 2791 2792
        "sync_stats": sync_stats,
        "summary_decay_rate": summary_decay_rate,
    }
    if slot_dim > 0:
        attrs["slot_dim"] = slot_dim
    if enable_scale_and_shift:
        attrs["enable_scale_and_shift"] = enable_scale_and_shift
2793 2794 2795
    if enable_scale_and_shift:
        inputs["scale_w"] = scale_w
        inputs["bias"] = bias
2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808
    helper.append_op(
        type="data_norm",
        inputs=inputs,
        outputs={
            "Y": data_norm_out,
            "Means": means,
            "Scales": scales,
            "BatchSize": batch_size,
            "BatchSum": batch_sum,
            "BatchSquareSum": batch_square_sum,
        },
        attrs=attrs,
    )
H
heqiaozhi 已提交
2809 2810 2811 2812

    return helper.append_activation(data_norm_out)


Y
yuyang18 已提交
2813
@templatedoc()
2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824
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,
):
2825
    r"""
2826 2827
    :api_attr: Static Graph

2828 2829 2830 2831
    **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 已提交
2832 2833 2834

    The formula is as follows:

Y
yuyang18 已提交
2835
    ..  math::
G
guosheng 已提交
2836

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

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

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

2843 2844 2845 2846 2847
    - :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 已提交
2848

G
guosheng 已提交
2849
    Args:
2850
        input(Tensor): A multi-dimension ``Tensor`` , and the data type is float32 or float64.
2851 2852 2853 2854 2855
        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 已提交
2856
            dimensions from :attr:`begin_norm_axis` to :attr:`rank(input)`.
2857 2858 2859 2860
            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 已提交
2861 2862
            gain :math:`g`. If :attr:`scale` is False, :attr:`param_attr` is
            omitted. If :attr:`scale` is True and :attr:`param_attr` is None,
2863
            a default :code:`ParamAttr` would be added as scale. The
2864 2865
            :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 已提交
2866 2867
            bias :math:`b`. If :attr:`shift` is False, :attr:`bias_attr` is
            omitted. If :attr:`shift` is True and :attr:`param_attr` is None,
2868
            a default :code:`ParamAttr` would be added as bias. The
2869
            :attr:`bias_attr` is initialized as 0 if it is added. Default: None.
T
tianshuo78520a 已提交
2870
        act(str, optional): Activation to be applied to the output of layer normalization.
2871 2872
                  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 已提交
2873 2874

    Returns:
2875
        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 已提交
2876 2877 2878

    Examples:

2879 2880
        .. code-block:: python

2881 2882
            import paddle
            paddle.enable_static()
2883 2884 2885
            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 已提交
2886
    """
2887 2888 2889
    assert (
        _non_static_mode() is not True
    ), "please use LayerNorm instead of layer_norm in dygraph mode!"
G
guosheng 已提交
2890
    helper = LayerHelper('layer_norm', **locals())
2891 2892 2893
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'layer_norm'
    )
G
guosheng 已提交
2894 2895 2896 2897 2898 2899 2900
    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:
2901 2902 2903 2904 2905 2906 2907 2908 2909
        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 已提交
2910
        inputs['Scale'] = scale
2911 2912
    else:
        if param_attr:
T
tianshuo78520a 已提交
2913
            warnings.warn("param_attr is only available with scale is True.")
G
guosheng 已提交
2914
    if shift:
2915 2916 2917 2918 2919 2920
        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 已提交
2921
        inputs['Bias'] = bias
2922 2923
    else:
        if bias_attr:
T
tianshuo78520a 已提交
2924
            warnings.warn("bias_attr is only available with shift is True.")
G
guosheng 已提交
2925 2926

    # create output
2927 2928 2929 2930 2931 2932
    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 已提交
2933
    layer_norm_out = helper.create_variable_for_type_inference(dtype)
G
guosheng 已提交
2934

2935 2936 2937 2938 2939 2940 2941 2942 2943 2944
    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 已提交
2945 2946 2947 2948

    return helper.append_activation(layer_norm_out)


D
Dun 已提交
2949
@templatedoc()
2950 2951 2952 2953 2954 2955 2956 2957 2958 2959
def group_norm(
    input,
    groups,
    epsilon=1e-05,
    param_attr=None,
    bias_attr=None,
    act=None,
    data_layout='NCHW',
    name=None,
):
D
Dun 已提交
2960
    """
2961 2962
    :api_attr: Static Graph

D
Dun 已提交
2963 2964
    **Group Normalization Layer**

H
haowang101779990 已提交
2965
    Refer to `Group Normalization <https://arxiv.org/abs/1803.08494>`_ .
D
Dun 已提交
2966

2967
    Parameters:
2968
        input(Tensor): Tensor with dimension greater than 1, the data type is float32 or float64.
2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980
        groups(int): The number of groups that divided from channels, the data type
            is int32.
        epsilon(float, optional): The small value added to the variance to prevent
            division by zero, the data type is float32. Default: 1e-05.
        param_attr(ParamAttr|bool, optional): ParamAttr object that specifies weight parameter
            attribute. If a bool type, only False is supported, which means there is no weight parameter.
            Default: None, the default weight parameter attribute is used. For more information, please
            refer to :ref:`api_guide_ParamAttr` .
        bias_attr(ParamAttr|bool, optional): ParamAttr object that specifies bias parameter
            attribute. If a bool type, only False is supported, which means there is no bias parameter.
            Default: None, the default bias parameter attribute is used. For more information, please
            refer to :ref:`api_guide_ParamAttr` .
T
tianshuo78520a 已提交
2981
        act(str, optional): Activation to be applied to the output of group normalization.
2982
        data_layout(str, optional): Specify the data format of the input, and the data format of the output
2983 2984
            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:
2985
            `[batch_size, input_channels, *]`.
2986 2987
        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` .
D
Dun 已提交
2988 2989

    Returns:
2990
        Tensor: A Tensor has same data type and data format with `input`.
D
Dun 已提交
2991 2992

    Examples:
2993
       .. code-block:: python
D
Dun 已提交
2994

2995 2996
            import paddle
            paddle.enable_static()
2997

C
Chen Long 已提交
2998 2999 3000
            data = paddle.static.data(name='data', shape=[2, 8, 32, 32], dtype='float32')
            x = paddle.static.nn.group_norm(input=data, groups=4)
            print(x.shape) # [2, 8, 32, 32]
D
Dun 已提交
3001 3002 3003
    """
    helper = LayerHelper('group_norm', **locals())
    dtype = helper.input_dtype()
3004 3005 3006
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'group_norm'
    )
D
Dun 已提交
3007 3008 3009
    # create intput and parameters
    inputs = {'X': input}
    input_shape = input.shape
3010 3011 3012 3013
    if len(input_shape) < 2:
        raise ValueError(
            f"The dimensions of Op(fluid.layers.group_norm)'s input should be more than 1. But received {len(input_shape)}"
        )
3014 3015 3016
    if data_layout != 'NCHW' and data_layout != 'NHWC':
        raise ValueError(
            "Param(data_layout) of Op(fluid.layers.group_norm) got wrong value: received "
3017 3018 3019
            + data_layout
            + " but only NCHW or NHWC supported."
        )
3020 3021
    channel_num = input_shape[1] if data_layout == 'NCHW' else input_shape[-1]
    param_shape = [channel_num]
D
Dun 已提交
3022
    if param_attr:
3023 3024 3025 3026 3027 3028
        scale = helper.create_parameter(
            attr=helper.param_attr,
            shape=param_shape,
            dtype=dtype,
            default_initializer=Constant(1.0),
        )
D
Dun 已提交
3029 3030
        inputs['Scale'] = scale
    if bias_attr:
3031 3032 3033
        bias = helper.create_parameter(
            attr=helper.bias_attr, shape=param_shape, dtype=dtype, is_bias=True
        )
D
Dun 已提交
3034 3035 3036
        inputs['Bias'] = bias

    # create output
H
heqiaozhi 已提交
3037 3038
    mean_out = helper.create_variable(dtype=dtype, stop_gradient=True)
    variance_out = helper.create_variable(dtype=dtype, stop_gradient=True)
D
dengkaipeng 已提交
3039 3040
    group_norm_out = helper.create_variable(dtype=dtype)

3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054
    helper.append_op(
        type="group_norm",
        inputs=inputs,
        outputs={
            "Y": group_norm_out,
            "Mean": mean_out,
            "Variance": variance_out,
        },
        attrs={
            "epsilon": epsilon,
            "groups": groups,
            "data_layout": data_layout,
        },
    )
D
dengkaipeng 已提交
3055 3056 3057 3058 3059

    return helper.append_activation(group_norm_out)


@templatedoc()
3060
def spectral_norm(weight, dim=0, power_iters=1, eps=1e-12, name=None):
3061
    r"""
3062 3063
    :api_attr: Static Graph

D
dengkaipeng 已提交
3064 3065
    **Spectral Normalization Layer**

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

D
dengkaipeng 已提交
3071 3072 3073
    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 已提交
3074
    and W is the product result of remaining dimensions.
D
dengkaipeng 已提交
3075 3076

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

3081
    .. math::
D
dengkaipeng 已提交
3082 3083 3084 3085 3086 3087

        \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 已提交
3088
    Calculate :math:`\sigma(\mathbf{W})` and normalize weight values.
D
dengkaipeng 已提交
3089 3090 3091 3092

    .. math::

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

D
dengkaipeng 已提交
3094
        \mathbf{W} = \\frac{\mathbf{W}}{\sigma(\mathbf{W})}
3095

3096

D
dengkaipeng 已提交
3097 3098 3099
    Refer to `Spectral Normalization <https://arxiv.org/abs/1802.05957>`_ .

    Args:
C
Chen Long 已提交
3100
        weight(Tensor): ${weight_comment}
D
dengkaipeng 已提交
3101 3102 3103
        dim(int): ${dim_comment}
        power_iters(int): ${power_iters_comment}
        eps(float): ${eps_comment}
K
Kaipeng Deng 已提交
3104 3105 3106
        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 已提交
3107 3108

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

    Examples:
K
Kaipeng Deng 已提交
3113
       .. code-block:: python
D
dengkaipeng 已提交
3114

3115
            import paddle
K
Kaipeng Deng 已提交
3116

3117
            paddle.enable_static()
C
Chen Long 已提交
3118
            weight = paddle.static.data(name='weight', shape=[2, 8, 32, 32], dtype='float32')
3119
            x = paddle.static.nn.spectral_norm(weight=weight, dim=1, power_iters=2)
C
Chen Long 已提交
3120
            print(x.shape) # [2, 8, 32, 32]
D
dengkaipeng 已提交
3121 3122
    """
    helper = LayerHelper('spectral_norm', **locals())
3123 3124 3125
    check_variable_and_dtype(
        weight, 'weight', ['float32', 'float64'], 'spectral_norm'
    )
3126 3127 3128
    check_type(dim, 'dim', int, 'spectral_norm')
    check_type(power_iters, 'power_iters', int, 'spectral_norm')
    check_type(eps, 'eps', float, 'spectral_norm')
3129
    dtype = weight.dtype
D
dengkaipeng 已提交
3130 3131

    # create intput and parameters
3132
    input_shape = weight.shape
3133
    assert weight.numel() > 0, "Any dimension of input cannot be equal to 0."
3134 3135 3136 3137 3138
    assert dim < len(input_shape), (
        "The input `dim` should be less than the "
        "rank of `weight`, but received dim="
        "{}".format(dim)
    )
3139 3140 3141
    h = input_shape[dim]
    w = np.prod(input_shape) // h

3142 3143 3144 3145 3146 3147
    u = helper.create_parameter(
        attr=ParamAttr(),
        shape=[h],
        dtype=dtype,
        default_initializer=Normal(0.0, 1.0),
    )
3148
    u.stop_gradient = True
3149 3150 3151 3152 3153 3154
    v = helper.create_parameter(
        attr=ParamAttr(),
        shape=[w],
        dtype=dtype,
        default_initializer=Normal(0.0, 1.0),
    )
3155
    v.stop_gradient = True
D
dengkaipeng 已提交
3156

3157 3158 3159 3160 3161 3162 3163
    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 已提交
3164
    # create output
3165
    out = helper.create_variable(dtype=dtype)
D
Dun 已提交
3166

3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178
    helper.append_op(
        type="spectral_norm",
        inputs=inputs,
        outputs={
            "Out": out,
        },
        attrs={
            "dim": dim,
            "power_iters": power_iters,
            "eps": eps,
        },
    )
D
Dun 已提交
3179

3180
    return out
D
Dun 已提交
3181 3182


C
caoying03 已提交
3183
def reduce_sum(input, dim=None, keep_dim=False, name=None):
G
guosheng 已提交
3184
    """
3185

Y
yangyaming 已提交
3186
    Computes the sum of tensor elements over the given dimension.
G
guosheng 已提交
3187 3188

    Args:
3189 3190 3191
        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 已提交
3192 3193
            :attr:`None`, sum all elements of :attr:`input` and return a
            Tensor variable with a single element, otherwise must be in the
W
whs 已提交
3194 3195
            range :math:`[-rank(input), rank(input))`. If :math:`dim[i] < 0`,
            the dimension to reduce is :math:`rank + dim[i]`.
3196
        keep_dim (bool, optional): Whether to reserve the reduced dimension in the
Y
yangyaming 已提交
3197
            output Tensor. The result tensor will have one fewer dimension
3198 3199 3200 3201
            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 已提交
3202 3203

    Returns:
3204 3205
        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 已提交
3206

3207 3208
    Raises:
        TypeError, if out data type is different with the input data type.
3209

G
guosheng 已提交
3210 3211 3212
    Examples:
        .. code-block:: python

3213
            import paddle.fluid as fluid
3214 3215
            import paddle
            paddle.enable_static()
G
guosheng 已提交
3216 3217 3218
            # 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 已提交
3219
            # Each example is followed by the corresponding output tensor.
3220
            x = fluid.data(name='x', shape=[2, 4], dtype='float32')
G
guosheng 已提交
3221 3222 3223 3224
            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 已提交
3225

3226
            # y is a Tensor variable with shape [2, 2, 2] and elements as below:
W
whs 已提交
3227 3228
            #      [[[1, 2], [3, 4]],
            #      [[5, 6], [7, 8]]]
Q
qiaolongfei 已提交
3229
            # Each example is followed by the corresponding output tensor.
3230
            y = fluid.data(name='y', shape=[2, 2, 2], dtype='float32')
3231 3232
            fluid.layers.reduce_sum(y, dim=[1, 2]) # [10, 26]
            fluid.layers.reduce_sum(y, dim=[0, 1]) # [16, 20]
W
whs 已提交
3233

G
guosheng 已提交
3234
    """
3235 3236
    reduce_all, dim = _get_reduce_dim(dim, input)

3237
    if in_dygraph_mode():
3238
        return _C_ops.sum(input, dim, None, keep_dim)
3239
    elif _in_legacy_dygraph():
3240 3241 3242
        return _legacy_C_ops.reduce_sum(
            input, 'dim', dim, 'keep_dim', keep_dim, 'reduce_all', reduce_all
        )
3243
    attrs = {'dim': dim, 'keep_dim': keep_dim, 'reduce_all': reduce_all}
3244
    check_variable_and_dtype(
3245 3246 3247 3248 3249
        input,
        'input',
        ['float16', 'float32', 'float64', 'int32', 'int64'],
        'reduce_sum',
    )
3250
    helper = LayerHelper('reduce_sum', **locals())
X
Xin Pan 已提交
3251
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
3252 3253 3254 3255 3256 3257
    helper.append_op(
        type='reduce_sum',
        inputs={'X': input},
        outputs={'Out': out},
        attrs=attrs,
    )
G
guosheng 已提交
3258
    return out
G
guosheng 已提交
3259 3260


3261
@deprecated(since="2.0.0", update_to="paddle.mean")
C
caoying03 已提交
3262
def reduce_mean(input, dim=None, keep_dim=False, name=None):
G
guosheng 已提交
3263
    """
Y
Yibing Liu 已提交
3264
    Computes the mean of the input tensor's elements along the given dimension.
G
guosheng 已提交
3265 3266

    Args:
3267 3268 3269
        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 已提交
3270 3271
            `None`, compute the mean over all elements of :attr:`input`
            and return a variable with a single element, otherwise it
Y
yangyaming 已提交
3272
            must be in the range :math:`[-rank(input), rank(input))`. If
3273
            :math:`dim[i] < 0`, the dimension to reduce is
Y
Yibing Liu 已提交
3274
            :math:`rank(input) + dim[i]`.
3275
        keep_dim (bool, optional): Whether to reserve the reduced dimension in the
Y
yangyaming 已提交
3276
            output Tensor. The result tensor will have one fewer dimension
3277
            than the :attr:`input` unless :attr:`keep_dim` is true, default
3278 3279 3280
            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`
3281

G
guosheng 已提交
3282
    Returns:
3283 3284
        Variable: Tensor, results of average on the specified dim of input tensor,
        it's data type is the same as input's Tensor.
3285

3286 3287
    Raises:
        TypeError, if out data type is different with the input data type.
3288

G
guosheng 已提交
3289 3290 3291
    Examples:
        .. code-block:: python

3292
            import paddle
3293
            import paddle.fluid as fluid
3294 3295
            paddle.enable_static()

G
guosheng 已提交
3296 3297 3298
            # 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 已提交
3299
            # Each example is followed by the corresponding output tensor.
3300
            x = fluid.data(name='x', shape=[2, 4], dtype='float32')
G
guosheng 已提交
3301 3302 3303
            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]
3304
            fluid.layers.reduce_mean(x, dim=1, keep_dim=True)  # [[0.475], [0.4]]
W
whs 已提交
3305

3306
            # y is a Tensor variable with shape [2, 2, 2] and elements as below:
W
whs 已提交
3307 3308
            #      [[[1.0, 2.0], [3.0, 4.0]],
            #      [[5.0, 6.0], [7.0, 8.0]]]
T
tianshuo78520a 已提交
3309
            # Each example is followed by the corresponding output tensor.
3310
            y = fluid.data(name='y', shape=[2, 2, 2], dtype='float32')
3311 3312
            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 已提交
3313
    """
3314

3315
    return paddle.mean(x=input, axis=dim, keepdim=keep_dim, name=name)
3316 3317


Z
zhoukunsheng 已提交
3318 3319
def reduce_all(input, dim=None, keep_dim=False, name=None):
    """
3320

3321
    This OP computes the ``logical and`` of tensor elements over the given dimension, and output the result.
Z
zhoukunsheng 已提交
3322 3323

    Args:
3324
        input (Tensor): the input tensor, it's data type should be `bool`.
3325
        dim (list|int|optional): The dimension along which the logical and is computed.
Z
zhoukunsheng 已提交
3326 3327 3328
            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))`.
3329
            If :math:`dim[i] < 0`, the dimension to reduce is :math:`rank + dim[i]`. The default value is None.
Z
zhoukunsheng 已提交
3330 3331
        keep_dim (bool): Whether to reserve the reduced dimension in the
            output Tensor. The result tensor will have one fewer dimension
3332
            than the :attr:`input` unless :attr:`keep_dim` is true. The default value is False.
Z
zhoukunsheng 已提交
3333
        name(str|None): A name for this layer(optional). If set None, the layer
3334
                       will be named automatically. The default value is None.
Z
zhoukunsheng 已提交
3335

3336
    Returns:
3337
        Tensor, the output data type is bool. : The reduced tensor variable with ``logical and`` in given dims.
Z
zhoukunsheng 已提交
3338 3339 3340

    Examples:
        .. code-block:: python
3341

3342
            import paddle
3343
            import paddle.fluid as fluid
3344 3345 3346
            import paddle.fluid.layers as layers
            import numpy as np

Z
zhoukunsheng 已提交
3347 3348 3349
            # x is a bool Tensor variable with following elements:
            #    [[True, False]
            #     [True, True]]
3350 3351
            x = fluid.layers.assign(np.array([[1, 0], [1, 1]], dtype='int32'))
            x = fluid.layers.cast(x, 'bool')
3352

3353 3354 3355
            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]
3356 3357
            # keep_dim=False, x.shape=(2,2), out.shape=(2,)

3358
            out = fluid.layers.reduce_all(x, dim=1, keep_dim=True)  # [[False], [True]]
3359
            # keep_dim=True, x.shape=(2,2), out.shape=(2,1)
Z
zhoukunsheng 已提交
3360 3361

    """
3362 3363
    if dim is not None and not isinstance(dim, list):
        dim = [dim]
3364 3365

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

3368
    check_variable_and_dtype(input, 'input', ('bool'), 'reduce_all')
Z
zhoukunsheng 已提交
3369 3370
    helper = LayerHelper('reduce_all', **locals())
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
3371 3372 3373 3374 3375
    helper.append_op(
        type='reduce_all',
        inputs={'X': input},
        outputs={'Out': out},
        attrs={
3376
            'dim': dim if dim is not None and dim != [] else [0],
3377 3378
            'keep_dim': keep_dim,
            'reduce_all': True
3379
            if dim is None or dim == [] or len(dim) == len(input.shape)
3380 3381 3382
            else False,
        },
    )
Z
zhoukunsheng 已提交
3383 3384 3385 3386 3387
    return out


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

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

3402
    Returns:
3403
        Tensor, the output data type is bool. : The reduced tensor variable with ``logical or`` in given dims.
Z
zhoukunsheng 已提交
3404 3405 3406

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

3408
            import paddle
3409
            import paddle.fluid as fluid
3410 3411 3412
            import paddle.fluid.layers as layers
            import numpy as np

Z
zhoukunsheng 已提交
3413 3414 3415
            # x is a bool Tensor variable with following elements:
            #    [[True, False]
            #     [False, False]]
3416 3417
            x = fluid.layers.assign(np.array([[1, 0], [0, 0]], dtype='int32'))
            x = fluid.layers.cast(x, 'bool')
3418

3419 3420 3421
            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]
3422 3423
            # keep_dim=False, x.shape=(2,2), out.shape=(2,)

3424
            out = fluid.layers.reduce_any(x, dim=1,
Z
zhoukunsheng 已提交
3425
                                     keep_dim=True)  # [[True], [False]]
3426
            # keep_dim=True, x.shape=(2,2), out.shape=(2,1)
Z
zhoukunsheng 已提交
3427 3428

    """
3429
    check_variable_and_dtype(input, 'input', ('bool'), 'reduce_any')
Z
zhoukunsheng 已提交
3430 3431 3432 3433
    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]
3434 3435 3436 3437 3438
    helper.append_op(
        type='reduce_any',
        inputs={'X': input},
        outputs={'Out': out},
        attrs={
3439
            'dim': dim if dim is not None and dim != [] else [0],
3440 3441
            'keep_dim': keep_dim,
            'reduce_all': True
3442
            if dim is None or dim == [] or len(dim) == len(input.shape)
3443 3444 3445
            else False,
        },
    )
3446 3447 3448
    return out


C
caoying03 已提交
3449
def split(input, num_or_sections, dim=-1, name=None):
G
guosheng 已提交
3450
    """
3451
    Split the input tensor into multiple sub-Tensors.
G
guosheng 已提交
3452 3453

    Args:
3454
        input (Tensor): A N-D Tensor. The data type is bool, float16, float32, float64, int32 or int64.
3455
        num_or_sections (int|list|tuple): If ``num_or_sections`` is int, then the ``num_or_sections``
3456
            indicates the number of equal sized sub-Tensors that the ``input``
3457
            will be divided into. If ``num_or_sections`` is a list or tuple, the length of it
3458 3459 3460 3461 3462
            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.
3463
        name (str, optional): The default value is None.  Normally there is no need for user to set this property.
3464
            For more information, please refer to :ref:`api_guide_Name` .
G
guosheng 已提交
3465 3466

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

3469
    Example:
G
guosheng 已提交
3470 3471
        .. code-block:: python

3472 3473
            import paddle.fluid as fluid

3474
            # input is a Tensor which shape is [3, 9, 5]
3475
            input = fluid.data(
3476 3477
                 name="input", shape=[3, 9, 5], dtype="float32")

3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491
            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]
3492

3493 3494 3495 3496 3497 3498
            # 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]
3499

G
guosheng 已提交
3500
    """
J
Jiabin Yang 已提交
3501
    if _non_static_mode():
3502 3503 3504
        num = None
        attrs = ()

S
songyouwei 已提交
3505 3506
        if isinstance(dim, Variable):
            dim = dim.numpy()
3507
            dim = dim.item(0)
W
wangzhen38 已提交
3508
        assert len(input.shape) + dim >= 0, "(rank(x) + axis) must >= 0"
S
songyouwei 已提交
3509
        dim = (len(input.shape) + dim) if dim < 0 else dim
3510
        attrs += ('axis', dim)
3511 3512 3513

        if isinstance(num_or_sections, int):
            num = num_or_sections
3514
            attrs += ('num', num_or_sections)
L
Leo Chen 已提交
3515
        elif isinstance(num_or_sections, (list, tuple)):
3516
            num = len(num_or_sections)
L
Leo Chen 已提交
3517
            if utils._contain_var(num_or_sections):
3518 3519
                for index, item in enumerate(num_or_sections):
                    if isinstance(item, Variable):
3520 3521 3522
                        num_or_sections[index] = num_or_sections[index].numpy()[
                            0
                        ]
3523
                attrs += ('sections', list(num_or_sections))
L
Leo Chen 已提交
3524
            else:
3525
                attrs += ('sections', list(num_or_sections))
3526 3527
        else:
            raise TypeError(
3528
                "The type of 'num_or_sections' in split must be int, list or tuple in imperative mode, but "
3529 3530
                "received %s." % (type(num_or_sections))
            )
3531
        if in_dygraph_mode():
C
Charles-hit 已提交
3532 3533 3534 3535
            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)
3536 3537
        elif _in_legacy_dygraph():
            out = [_varbase_creator() for n in range(num)]
3538
            _legacy_C_ops.split(input, out, *attrs)
3539
            return out
L
Leo Chen 已提交
3540

3541
    check_variable_and_dtype(
3542 3543 3544 3545 3546
        input,
        'input',
        ['bool', 'float16', 'float32', 'float64', 'int32', 'int64'],
        'split',
    )
3547 3548 3549 3550
    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')
3551

G
guosheng 已提交
3552
    helper = LayerHelper('split', **locals())
3553

G
guosheng 已提交
3554
    input_shape = input.shape
3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565
    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:
3566
                assert isinstance(dim_size, int)
3567 3568 3569
                if dim_size == -1:
                    assert unk_dim_idx == -1, (
                        "Only one value of 'num_or_section' in split can "
3570 3571 3572
                        "be -1. But received num_or_section[%d] is also -1."
                        % idx
                    )
3573 3574
                    unk_dim_idx = idx
                temp_out = helper.create_variable_for_type_inference('int32')
3575 3576 3577
                fill_constant(
                    [1], 'int32', dim_size, force_cpu=True, out=temp_out
                )
3578 3579 3580 3581 3582 3583 3584
                tensor_list.append(temp_out)
        return tensor_list

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

G
guosheng 已提交
3589 3590
    if isinstance(num_or_sections, int):
        assert num_or_sections > 1, 'num_or_sections must be more than 1.'
3591
        if isinstance(dim, int) and input_shape[dim] > 0:
3592 3593 3594 3595 3596 3597
            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 已提交
3598 3599
        num = num_or_sections
    else:
3600
        if isinstance(dim, int) and input_shape[dim] > 0:
3601 3602 3603
            assert (
                len(num_or_sections) <= input_shape[dim]
            ), 'len(num_or_sections) must not be more than input.shape[dim].'
G
guosheng 已提交
3604
        num = len(num_or_sections)
3605
        attrs['sections'] = list(
3606 3607 3608 3609 3610
            map(
                lambda ele: -1 if isinstance(ele, Variable) else ele,
                num_or_sections,
            )
        )
L
Leo Chen 已提交
3611
        if utils._contain_var(num_or_sections):
3612
            inputs['SectionsTensorList'] = _get_SectionsTensorList(
3613 3614
                num_or_sections
            )
3615

G
guosheng 已提交
3616
    outs = [
X
Xin Pan 已提交
3617
        helper.create_variable_for_type_inference(dtype=helper.input_dtype())
G
guosheng 已提交
3618 3619
        for i in range(num)
    ]
3620 3621 3622
    helper.append_op(
        type='split', inputs=inputs, outputs={'Out': outs}, attrs=attrs
    )
G
guosheng 已提交
3623
    return outs
C
caoying03 已提交
3624 3625 3626


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

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

3632
    .. math::
3633 3634

        y = \\frac{x}{ \sqrt{\sum {x^2} + epsion }}
C
caoying03 已提交
3635 3636 3637 3638 3639

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

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

C
caoying03 已提交
3648
    Returns:
R
ruri 已提交
3649
        Variable: The output has the same shape and data type with `x`.
C
caoying03 已提交
3650 3651

    Examples:
3652

3653 3654
    .. code-block:: python
        :name: code-example1
3655

3656
        import paddle
3657

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

3662 3663 3664
        # [[ 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]]
3665

C
caoying03 已提交
3666
    """
F
fengjiayi 已提交
3667 3668
    if len(x.shape) == 1:
        axis = 0
J
Jiabin Yang 已提交
3669
    if _non_static_mode():
3670 3671 3672
        if in_dygraph_mode():
            out, _ = _C_ops.norm(x, 1 if axis is None else axis, epsilon, False)
        elif _in_legacy_dygraph():
3673 3674 3675
            _, out = _legacy_C_ops.norm(
                x, 'axis', 1 if axis is None else axis, 'epsilon', epsilon
            )
3676 3677 3678
        return out

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

3680
    helper = LayerHelper("l2_normalize", **locals())
X
Xin Pan 已提交
3681 3682
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
    norm = helper.create_variable_for_type_inference(dtype=x.dtype)
3683 3684 3685 3686 3687 3688 3689 3690 3691
    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 已提交
3692
    return out
3693 3694


S
ShenLiang 已提交
3695
@deprecated(since="2.0.0", update_to="paddle.matmul")
S
sneaxiy 已提交
3696
def matmul(x, y, transpose_x=False, transpose_y=False, alpha=1.0, name=None):
G
guosheng 已提交
3697
    """
Y
ying 已提交
3698 3699 3700 3701
    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 已提交
3702

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

3706 3707 3708 3709 3710
    - 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
3711
      :math:`[1, D]` in transposed form.
G
guosheng 已提交
3712

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

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

Y
ying 已提交
3721 3722
    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 已提交
3723
    removed after matrix multiplication.
G
guosheng 已提交
3724 3725 3726

    Args:
        x (Variable): The input variable which is a Tensor or LoDTensor.
3727 3728 3729
        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 已提交
3730
        alpha (float): The scale of output. Default 1.0.
3731
        name(str|None): A name for this layer(optional). If set None, the layer
3732
            will be named automatically.
G
guosheng 已提交
3733 3734

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

G
guosheng 已提交
3737 3738 3739
    Examples:
        .. code-block:: python

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

3744
            # x: [B, M, K], y: [B, K, N]
3745
            # fluid.layers.matmul(x, y)  # out: [B, M, N]
Y
ying 已提交
3746

3747
            # x: [B, M, K], y: [K, N]
3748
            # fluid.layers.matmul(x, y)  # out: [B, M, N]
Y
ying 已提交
3749

3750
            # x: [M, K], y: [K, N]
3751
            # fluid.layers.matmul(x, y)  # out: [M, N]
Y
ying 已提交
3752 3753

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

3756
            # x: [K], y: [K]
3757
            # fluid.layers.matmul(x, y)  # out: [1]
3758

Y
ying 已提交
3759
            # x: [M], y: [N]
3760 3761
            # fluid.layers.matmul(x, y, True, True)  # out: [M, N]

3762
            import paddle
3763
            import paddle.fluid as fluid
3764 3765
            paddle.enable_static()

3766 3767 3768
            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 已提交
3769
    """
J
Jiabin Yang 已提交
3770
    if _non_static_mode():
S
ShenLiang 已提交
3771
        out = _varbase_creator(dtype=x.dtype)
3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782
        _legacy_C_ops.matmul(
            x,
            y,
            out,
            'transpose_X',
            transpose_x,
            'transpose_Y',
            transpose_y,
            'alpha',
            float(alpha),
        )
S
ShenLiang 已提交
3783 3784 3785 3786 3787
        return out

    def __check_input(x, y):
        var_names = {'x': x, 'y': y}
        for name, val in var_names.items():
3788 3789 3790
            check_variable_and_dtype(
                val, name, ['float16', 'float32', 'float64'], 'matmul'
            )
S
ShenLiang 已提交
3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803
        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]:
3804 3805 3806 3807 3808 3809
            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 已提交
3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820

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

W
wanghuancoder 已提交
3824 3825 3826 3827 3828 3829
    attrs = {
        'transpose_X': transpose_x,
        'transpose_Y': transpose_y,
        'alpha': float(alpha),
    }

S
ShenLiang 已提交
3830 3831 3832 3833
    __check_input(x, y)

    helper = LayerHelper('matmul', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
3834 3835 3836 3837 3838 3839
    helper.append_op(
        type='matmul',
        inputs={'X': x, 'Y': y},
        outputs={'Out': out},
        attrs=attrs,
    )
S
ShenLiang 已提交
3840
    return out
3841 3842


3843
def topk(input, k, name=None):
Q
qingqing01 已提交
3844
    """
3845
    :alias_main: paddle.topk
3846 3847
        :alias: paddle.topk,paddle.tensor.topk,paddle.tensor.search.topk
        :old_api: paddle.fluid.layers.topk
3848

3849
    This OP is used to find values and indices of the k largest entries
Q
qingqing01 已提交
3850 3851
    for the last dimension.

3852 3853
    If the input is a 1-D Tensor, finds the k largest entries and outputs
    their values and indices.
Q
qingqing01 已提交
3854 3855 3856 3857

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

F
fengjiayi 已提交
3858 3859
    .. code-block:: text

3860 3861 3862 3863 3864
        Case 1:

          Input:
            input.shape = [3, 4]
            input.data = [[5, 4, 2, 3],
F
fengjiayi 已提交
3865 3866 3867 3868
                     [9, 7, 10, 25],
                     [6, 2, 10, 1]]
            k = 2

3869
          Output:
F
fengjiayi 已提交
3870
            The first output:
3871 3872
            values.shape = [3, 2]
            values.data = [[5, 4],
F
fengjiayi 已提交
3873 3874 3875 3876
                      [10, 25],
                      [6, 10]]

            The second output:
3877 3878
            indices.shape = [3, 2]
            indices.data = [[0, 1],
F
fengjiayi 已提交
3879 3880 3881
                       [2, 3],
                       [0, 2]]

Q
qingqing01 已提交
3882
    Args:
3883 3884 3885 3886
        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 已提交
3887 3888

    Returns:
3889 3890
        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 已提交
3891

F
fengjiayi 已提交
3892
    Raises:
3893
        ValueError: If :math:`k < 1` or :math:`k > last dimension of input`.
Q
qingqing01 已提交
3894 3895 3896 3897

    Examples:
        .. code-block:: python

3898
            import paddle.fluid as fluid
3899
            import paddle.fluid.layers as layers
3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912
            # 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 已提交
3913
    """
J
Jiabin Yang 已提交
3914
    if _non_static_mode():
3915
        _k = k.numpy().item(0) if isinstance(k, Variable) else k
3916
        out, indices = _legacy_C_ops.top_k(input, 'k', _k)
3917 3918 3919
        out.stop_gradient = True
        indices.stop_gradient = True
        return out, indices
3920

3921 3922
    inputs = {"X": [input]}
    attrs = {}
S
songyouwei 已提交
3923 3924 3925 3926 3927
    if isinstance(k, Variable):
        inputs['K'] = [k]
    else:
        attrs = {'k': k}

3928 3929 3930 3931
    helper = LayerHelper("top_k", **locals())
    values = helper.create_variable_for_type_inference(dtype=input.dtype)
    indices = helper.create_variable_for_type_inference(dtype="int64")

3932 3933 3934 3935 3936 3937
    helper.append_op(
        type="top_k",
        inputs=inputs,
        outputs={"Out": [values], "Indices": [indices]},
        attrs=attrs,
    )
Q
qingqing01 已提交
3938 3939 3940 3941 3942
    values.stop_gradient = True
    indices.stop_gradient = True
    return values, indices


3943 3944 3945
def ctc_greedy_decoder(
    input, blank, input_length=None, padding_value=0, name=None
):
3946
    r"""
S
SunGaofeng 已提交
3947
    This op is used to decode sequences by greedy policy by the following steps:
Y
yi.wu 已提交
3948

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

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

3958 3959 3960 3961 3962
    A simple example as below:

    .. code-block:: text

        Given:
S
SunGaofeng 已提交
3963
        (1) for lod mode:
3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974

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

3975
        input.lod = [[4, 4]]
M
minqiyang 已提交
3976

W
whs 已提交
3977
        Computation:
3978

W
whs 已提交
3979 3980 3981 3982 3983 3984
        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:
3985 3986 3987 3988 3989

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

3990
        output.lod = [[2, 1]]
3991

S
SunGaofeng 已提交
3992
        (2) for padding mode:
3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008

         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]
4009
        step2: Change the argmax result to use padding mode, then argmax result is
4010 4011 4012 4013 4014 4015 4016 4017 4018
                [[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 已提交
4019
    Parameters:
4020

4021 4022
        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 已提交
4023
                         where Lp is the sum of all input sequences' length and
4024 4025
                         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 已提交
4026
                         (not including the blank label). The data type can be float32 or float64.
Y
ying 已提交
4027
        blank(int): the blank label index of Connectionist Temporal
S
SunGaofeng 已提交
4028
                    Classification (CTC) loss, which is in the half-opened
Y
ying 已提交
4029
                    interval [0, num_classes + 1).
S
SunGaofeng 已提交
4030 4031
        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.
4032
        padding_value(int): padding value.
4033 4034 4035
        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`
4036 4037

    Returns:
S
SunGaofeng 已提交
4038 4039 4040 4041 4042
        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 [[]].

4043
        For padding mode, returns a tuple of (output, output_length), which was described as below:
S
SunGaofeng 已提交
4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054

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

4055 4056 4057 4058

    Examples:
        .. code-block:: python

4059
            # for lod mode
S
SunGaofeng 已提交
4060
            import paddle.fluid as fluid
S
SunGaofeng 已提交
4061
            x = fluid.data(name='x', shape=[None, 8], dtype='float32', lod_level=1)
4062
            cost = fluid.layers.ctc_greedy_decoder(input=x, blank=0)
4063 4064

            # for padding mode
S
SunGaofeng 已提交
4065 4066
            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')
4067 4068 4069
            out, out_len = fluid.layers.ctc_greedy_decoder(input=x_pad, blank=0,
                            input_length=x_pad_len)

W
wanghaoshuang 已提交
4070
    """
4071 4072 4073
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'ctc_greedy_decoder'
    )
4074

4075
    helper = LayerHelper("ctc_greedy_decoder", **locals())
Q
qingqing01 已提交
4076
    _, topk_indices = topk(input, k=1)
4077 4078

    # ctc align op
X
Xin Pan 已提交
4079
    ctc_out = helper.create_variable_for_type_inference(dtype="int64")
4080 4081

    if input_length is None:
4082 4083 4084 4085 4086 4087
        helper.append_op(
            type="ctc_align",
            inputs={"Input": [topk_indices]},
            outputs={"Output": [ctc_out]},
            attrs={"merge_repeated": True, "blank": blank},
        )
4088 4089 4090
        return ctc_out
    else:
        ctc_out_len = helper.create_variable_for_type_inference(dtype="int64")
4091
        ctc_input = paddle.squeeze(topk_indices, [2])
4092

4093 4094 4095 4096 4097 4098 4099 4100 4101 4102
        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,
            },
        )
4103
        return ctc_out, ctc_out_len
4104 4105


4106 4107 4108 4109 4110 4111 4112 4113 4114
def im2sequence(
    input,
    filter_size=1,
    stride=1,
    padding=0,
    input_image_size=None,
    out_stride=1,
    name=None,
):
4115
    r"""
4116 4117
    :api_attr: Static Graph

4118
    Extracts image patches from the input tensor to form a tensor of shape
L
Liufang Sang 已提交
4119 4120 4121
    {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
4122 4123
    output_height * output_width for an image, in which output_height and
    output_width are calculated by below equation:
4124 4125 4126

    .. math::

L
Liufang Sang 已提交
4127 4128 4129 4130
        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
4131

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

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

L
Liufang Sang 已提交
4137 4138 4139
        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.
4140

L
Liufang Sang 已提交
4141 4142
        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.
4143

L
Liufang Sang 已提交
4144 4145 4146 4147 4148
        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
4149
            padding_up = padding_down = padding_left = padding_right = padding.
L
Liufang Sang 已提交
4150
            Default is 0.
4151

L
Liufang Sang 已提交
4152 4153 4154 4155
        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 已提交
4156
            If out_stride is List,  it must contain two integers,
L
Liufang Sang 已提交
4157 4158 4159 4160 4161
            :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` .
4162 4163 4164

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

    Return Type: Variable
4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194

    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 已提交
4195 4196 4197
            filter = [2, 2]
            stride = [1, 1]
            padding = [0, 0]
4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209

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

4210
            output.dims = {8, 8}
4211

4212
            output.lod = [[4, 4]]
4213

T
Tink_Y 已提交
4214
    Examples:
4215 4216 4217

        .. code-block:: python

B
Bai Yifan 已提交
4218
            import paddle.fluid as fluid
4219 4220
            import paddle
            paddle.enable_static()
L
Liufang Sang 已提交
4221
            data = fluid.data(name='data', shape=[None, 3, 32, 32],
B
Bai Yifan 已提交
4222
                                     dtype='float32')
4223
            output = fluid.layers.im2sequence(
B
Bai Yifan 已提交
4224 4225
                input=data, stride=[1, 1], filter_size=[2, 2])

4226 4227

    """
4228 4229 4230
    assert (
        not _non_static_mode()
    ), "sequence layer is not supported in dygraph mode yet."
W
wanghaoshuang 已提交
4231

4232 4233
    check_variable_and_dtype(input, 'input', ['float32'], 'im2sequence')

W
wanghaoshuang 已提交
4234 4235 4236 4237 4238 4239 4240 4241 4242
    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])
4243
    inputs = {"X": input}
4244
    attrs = {"kernels": filter_size, "strides": stride, "paddings": padding}
4245 4246 4247 4248 4249
    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
4250
    helper = LayerHelper('im2sequence', **locals())
X
Xin Pan 已提交
4251
    out = helper.create_variable_for_type_inference(dtype=helper.input_dtype())
4252 4253 4254
    helper.append_op(
        type='im2sequence', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
4255
    return out
4256 4257


Y
yuyang18 已提交
4258
@templatedoc()
4259
def row_conv(input, future_context_size, param_attr=None, act=None):
Y
yuyang18 已提交
4260
    """
4261 4262
    :api_attr: Static Graph

Y
yuyang18 已提交
4263
    ${comment}
4264 4265

    Args:
Y
yuyang18 已提交
4266
        input (${x_type}): ${x_comment}.
Y
yangyaming 已提交
4267 4268
        future_context_size (int): Future context size. Please note, the shape
            of convolution kernel is [future_context_size + 1, D].
4269 4270 4271 4272 4273
        param_attr (ParamAttr): Attributes of parameters, including
            name, initializer etc.
        act (str): Non-linear activation to be applied to output variable.

    Returns:
Y
yuyang18 已提交
4274
        ${out_comment}.
4275 4276

    Examples:
B
Bai Yifan 已提交
4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288

      .. 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)
4289 4290
    """
    helper = LayerHelper('row_conv', **locals())
4291
    check_variable_and_dtype(input, 'input', ['float32'], 'row_conv')
4292
    dtype = helper.input_dtype()
4293
    filter_shape = [future_context_size + 1, input.shape[-1]]
4294 4295 4296
    filter_param = helper.create_parameter(
        attr=helper.param_attr, shape=filter_shape, dtype=dtype
    )
X
Xin Pan 已提交
4297
    out = helper.create_variable_for_type_inference(dtype)
4298 4299 4300 4301 4302
    helper.append_op(
        type='row_conv',
        inputs={'X': [input], 'Filter': [filter_param]},
        outputs={'Out': [out]},
    )
Y
yangyaming 已提交
4303
    return helper.append_activation(out)
4304 4305


Y
yuyang18 已提交
4306
@templatedoc()
4307
def multiplex(inputs, index, name=None):
4308
    """
Y
yuyang18 已提交
4309

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

4312
    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 已提交
4313

4314
    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 已提交
4315

4316
    For Example:
L
lujun 已提交
4317

4318
            .. code-block:: text
L
lujun 已提交
4319

4320
                Given:
L
lujun 已提交
4321

4322 4323 4324 4325
                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 已提交
4326

4327
                index = [[3],[0],[1],[2]]
L
lujun 已提交
4328

4329 4330 4331 4332
                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 已提交
4333 4334


4335
    Args:
4336 4337 4338 4339 4340
        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`.
4341
    Returns:
4342
        Tensor: Output of multiplex OP, with data type being float32, float64, int32, int64.
X
xuezhong 已提交
4343 4344

    Examples:
4345

X
xuezhong 已提交
4346 4347
        .. code-block:: python

4348
            import paddle
4349 4350 4351
            import numpy as np
            img1 = np.array([[1, 2], [3, 4]]).astype(np.float32)
            img2 = np.array([[5, 6], [7, 8]]).astype(np.float32)
4352 4353 4354
            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)
4355
            print(res) # [array([[5., 6.], [3., 4.]], dtype=float32)]
X
xuezhong 已提交
4356

4357
    """
4358 4359

    if _in_legacy_dygraph():
4360
        return _legacy_C_ops.multiplex(index, inputs)
4361
    if in_dygraph_mode():
4362
        return _C_ops.multiplex(inputs, index)
4363 4364
    helper = LayerHelper('multiplex', **locals())

4365 4366 4367
    check_type(inputs, 'inputs', (list), 'multiplex')
    if len(inputs) < 2:
        raise ValueError(
4368 4369
            "inputs should be a list object with at least 2 elements."
        )
4370
    for id, x in enumerate(inputs):
4371 4372 4373 4374 4375 4376
        check_variable_and_dtype(
            x,
            'input[' + str(id) + ']',
            ['float32', 'float64', 'int32', 'int64'],
            'multiplex',
        )
4377
    check_variable_and_dtype(index, "index", ['int32', 'int64'], 'multiplex')
4378 4379

    out = helper.create_variable_for_type_inference(inputs[0].dtype)
4380 4381 4382 4383 4384
    helper.append_op(
        type='multiplex',
        inputs={'X': inputs, 'Ids': index},
        outputs={'Out': [out]},
    )
4385
    return out
X
xuezhong 已提交
4386 4387


4388 4389
def smooth_l1(x, y, inside_weight=None, outside_weight=None, sigma=None):
    """
4390

Y
Yibing Liu 已提交
4391 4392
    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 已提交
4393
    For each instance, it computes the smooth L1 loss element by element first
T
tianshuo78520a 已提交
4394
    and then sums all the losses. So the shape of output Variable is
4395
    [batch_size, 1].
4396

4397 4398
    Args:
        x (Variable): A tensor with rank at least 2. The input value of smooth
Q
qingqing01 已提交
4399
            L1 loss op with shape [batch_size, dim1, ..., dimN].
4400
            A LoDTensor or Tensor with type float32.
4401
        y (Variable): A tensor with rank at least 2. The target value of smooth
Y
Yibing Liu 已提交
4402
            L1 loss op with same shape as :attr:`x`.
4403
            A LoDTensor or Tensor with type float32.
4404
        inside_weight (Variable|None):  A tensor with rank at least 2. This
4405 4406
            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 已提交
4407
            by this tensor element by element.
4408
            A Tensor with type float32.
4409
        outside_weight (Variable|None): A tensor with rank at least 2. This
4410 4411
            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 已提交
4412
            element by element.
4413
            A Tensor with type float32.
4414
        sigma (float|None): Hyper parameter of smooth L1 loss layer. A float
4415 4416
           scalar with default value 1.0.

4417
    Returns:
4418
        Variable: The output smooth L1 loss with shape [batch_size, 1].  A Tensor with type float32.
4419 4420 4421 4422

    Examples:
        .. code-block:: python

4423
            import paddle.fluid as fluid
4424
            import numpy as np
4425 4426
            import paddle
            paddle.enable_static()
4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437
            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)
4438

4439 4440 4441 4442
            #[array([[0.08220536],
            #       [0.36652038],
            #      [0.20541131]], dtype=float32)]

4443
    """
4444 4445
    check_variable_and_dtype(x, 'X', ['float32', 'float64'], 'smooth_l1_loss')
    check_variable_and_dtype(y, 'Y', ['float32', 'float64'], 'smooth_l1_loss')
4446

4447
    helper = LayerHelper('smooth_l1_loss', **locals())
4448

X
Xin Pan 已提交
4449 4450
    diff = helper.create_variable_for_type_inference(dtype=x.dtype)
    loss = helper.create_variable_for_type_inference(dtype=x.dtype)
4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461
    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},
    )
4462
    return loss
4463 4464


4465
@deprecated(since='2.0.0', update_to='paddle.nn.functional.one_hot')
4466
def one_hot(input, depth, allow_out_of_range=False):
4467
    """
4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505

    **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.],
4506
                        [0., 1., 0., 0.],
4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518
                        [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
4519
            The second dimension in X is 5, which is greater than depth.
4520 4521
            Allow_out_of_range =False means that does not allow the word id to exceed depth,
            so it throws an exception.
4522 4523

    Args:
4524 4525 4526
        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.
4527
        depth(scalar): An integer defining the :attr:`depth` of the one hot dimension. If input
4528
            is word id, depth is generally the dictionary size.
4529
        allow_out_of_range(bool): A bool value indicating whether the input
4530 4531 4532 4533
            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.
4534 4535

    Returns:
4536
        Variable: The one-hot representations of input. A Tensor or LoDTensor with type float32.
4537 4538

    Examples:
C
caoying03 已提交
4539
        .. code-block:: python
4540

4541
            import paddle
4542
            import paddle.fluid as fluid
4543 4544
            paddle.enable_static()

4545 4546 4547
            # 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)
4548
    """
J
Jiabin Yang 已提交
4549
    if _non_static_mode():
S
songyouwei 已提交
4550 4551 4552
        if isinstance(depth, Variable):
            depth = depth.numpy()
            assert depth.shape == (
4553 4554
                1,
            ), "depth of type Variable should have shape [1]"
4555
            depth = depth.item(0)
4556 4557 4558
        out = _legacy_C_ops.one_hot(
            input, 'depth', depth, 'allow_out_of_range', allow_out_of_range
        )
4559 4560
        out.stop_gradient = True
        return out
4561

4562
    helper = LayerHelper("one_hot", **locals())
4563
    check_variable_and_dtype(input, 'input', ['int32', 'int64'], 'one_hot')
4564
    check_type(depth, 'depth', (int, Variable), 'one_hot')
X
Xin Pan 已提交
4565
    one_hot_out = helper.create_variable_for_type_inference(dtype='float32')
4566

4567 4568
    if not isinstance(depth, Variable):
        # user attribute
4569
        inputs = {'X': input}
Y
Yi Liu 已提交
4570
        attrs = {'depth': depth, 'allow_out_of_range': allow_out_of_range}
4571
    else:
4572 4573 4574
        depth.stop_gradient = True
        inputs = {'X': input, 'depth_tensor': depth}
        attrs = {'allow_out_of_range': allow_out_of_range}
4575 4576 4577
    helper.append_op(
        type="one_hot", inputs=inputs, attrs=attrs, outputs={'Out': one_hot_out}
    )
4578
    one_hot_out.stop_gradient = True
4579
    return one_hot_out
Y
Yu Yang 已提交
4580 4581


Y
Yu Yang 已提交
4582
def autoincreased_step_counter(counter_name=None, begin=1, step=1):
Y
Yu Yang 已提交
4583
    """
4584 4585
    :api_attr: Static Graph

4586 4587
    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 已提交
4588
    and the step size is 1.
Y
Yu Yang 已提交
4589 4590

    Args:
Y
Yibing Liu 已提交
4591 4592 4593
        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 已提交
4594

4595
    Returns:
Y
Yibing Liu 已提交
4596
        Variable: The auto-increased Variable with data type int64.
Y
yi.wu 已提交
4597 4598 4599 4600

    Examples:
        .. code-block:: python

4601
           import paddle.fluid as fluid
4602 4603
           import paddle
           paddle.enable_static()
Y
yi.wu 已提交
4604
           global_step = fluid.layers.autoincreased_step_counter(
Y
Yibing Liu 已提交
4605
               counter_name='@LR_DECAY_COUNTER@', begin=0, step=1)
Y
Yu Yang 已提交
4606 4607
    """
    helper = LayerHelper('global_step_counter')
Y
Yu Yang 已提交
4608 4609
    if counter_name is None:
        counter_name = '@STEP_COUNTER@'
Y
Yu Yang 已提交
4610
    counter, is_new_var = helper.create_or_get_global_variable(
H
hong 已提交
4611 4612 4613 4614
        name=counter_name,
        dtype='int64',
        shape=[1],
        persistable=True,
4615 4616
        belong_to_optimizer=True,
    )
Y
Yu Yang 已提交
4617
    if is_new_var:
4618 4619 4620
        helper.set_variable_initializer(
            counter, initializer=Constant(value=begin - 1, force_cpu=True)
        )
W
Wu Yi 已提交
4621
        helper.main_program.global_block()._prepend_op(
Y
Yu Yang 已提交
4622 4623
            type='increment',
            inputs={'X': [counter]},
Y
Yu Yang 已提交
4624
            outputs={'Out': [counter]},
4625 4626
            attrs={'step': float(step)},
        )
Y
Yu Yang 已提交
4627 4628 4629
        counter.stop_gradient = True

    return counter
Y
yangyaming 已提交
4630 4631


4632
def unsqueeze(input, axes, name=None):
Y
Yibing Liu 已提交
4633
    """
4634
    Insert single-dimensional entries to the shape of a Tensor. Takes one
M
minqiyang 已提交
4635 4636
    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 已提交
4637

M
minqiyang 已提交
4638
    For example:
H
haowang101779990 已提交
4639 4640 4641

    .. code-block:: text

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

Y
Yibing Liu 已提交
4645
    Args:
4646
        input (Variable): The input Tensor to be unsqueezed. Supported data type: float32, float64, bool, int8, int32, int64.
4647
        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 .
4648
        name (str|None): Name for this layer.
Y
Yibing Liu 已提交
4649 4650

    Returns:
4651
        Variable: Unsqueezed Tensor, with the same data type as input.
Y
Yibing Liu 已提交
4652 4653 4654 4655

    Examples:
        .. code-block:: python

4656 4657 4658
            import paddle.fluid as fluid
            x = fluid.layers.data(name='x', shape=[5, 10])
            y = fluid.layers.unsqueeze(input=x, axes=[1])
4659

Y
Yibing Liu 已提交
4660
    """
J
Jiabin Yang 已提交
4661
    if _non_static_mode():
L
Leo Chen 已提交
4662 4663 4664
        if isinstance(axes, int):
            axes = [axes]
        elif isinstance(axes, Variable):
4665
            axes = axes.numpy().tolist()
L
Leo Chen 已提交
4666 4667 4668 4669 4670
        elif isinstance(axes, (list, tuple)):
            axes = [
                item.numpy().item(0) if isinstance(item, Variable) else item
                for item in axes
            ]
4671
        if _in_legacy_dygraph():
4672
            out, _ = _legacy_C_ops.unsqueeze2(input, 'axes', axes)
4673
            return out
4674
        return _C_ops.unsqueeze(input, axes)
4675 4676

    check_type(axes, 'axis/axes', (int, list, tuple, Variable), 'unsqueeze')
4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693
    check_variable_and_dtype(
        input,
        'input',
        [
            'float16',
            'float32',
            'float64',
            'bool',
            'int8',
            'int16',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        'unsqueeze',
    )
4694 4695 4696 4697 4698 4699 4700 4701 4702 4703
    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 已提交
4704
        if utils._contain_var(axes):
4705
            inputs["AxesTensorList"] = utils._convert_to_tensor_list(axes)
4706 4707 4708
        else:
            attrs["axes"] = axes

X
Xin Pan 已提交
4709 4710
    out = helper.create_variable_for_type_inference(dtype=input.dtype)
    x_shape = helper.create_variable_for_type_inference(dtype=input.dtype)
4711 4712 4713 4714 4715 4716
    helper.append_op(
        type="unsqueeze2",
        inputs=inputs,
        attrs=attrs,
        outputs={"Out": out, "XShape": x_shape},
    )
Y
Yibing Liu 已提交
4717

4718 4719
    return out

4720

Y
yangyaming 已提交
4721
def lod_reset(x, y=None, target_lod=None):
Y
yangyaming 已提交
4722
    """
Y
Yibing Liu 已提交
4723
    Set LoD of :attr:`x` to a new one specified by :attr:`y` or
4724 4725 4726 4727
    :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
4728
    :attr:`y.data` or :attr:`target_lod`, only one level LoD is supported.
Y
yangyaming 已提交
4729 4730 4731 4732 4733 4734

    .. code-block:: text

        * Example 1:

            Given a 1-level LoDTensor x:
4735
                x.lod =  [[ 2,           3,                   1 ]]
Y
yangyaming 已提交
4736 4737 4738
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

4739
            target_lod: [4, 2]
Y
yangyaming 已提交
4740 4741

            then we get a 1-level LoDTensor:
4742
                out.lod =  [[4,                          2]]
Y
yangyaming 已提交
4743 4744 4745 4746 4747 4748
                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:
4749
                x.lod =  [[2,            3,                   1]]
Y
yangyaming 已提交
4750 4751 4752 4753
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

            y is a Tensor:
4754
                y.data = [[2, 4]]
Y
yangyaming 已提交
4755 4756 4757
                y.dims = [1, 3]

            then we get a 1-level LoDTensor:
4758
                out.lod =  [[2,            4]]
Y
yangyaming 已提交
4759 4760 4761 4762 4763 4764
                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:
4765
                x.lod =  [[2,            3,                   1]]
Y
yangyaming 已提交
4766 4767 4768 4769
                x.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                x.dims = [6, 1]

            y is a 2-level LoDTensor:
4770
                y.lod =  [[2, 2], [2, 2, 1, 1]]
Y
yangyaming 已提交
4771 4772 4773 4774
                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:
4775
                out.lod =  [[2, 2], [2, 2, 1, 1]]
Y
yangyaming 已提交
4776 4777 4778 4779
                out.data = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0]]
                out.dims = [6, 1]

    Args:
4780
        x (Variable): Input variable which could be a Tensor or LoDTensor.
4781
                      The data type should be int32, int64, float32 or float64.
4782 4783
        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.
4784 4785
                                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 已提交
4786
                                      as target LoD when :attr:`y` not provided.
Y
yangyaming 已提交
4787 4788

    Returns:
Y
Yibing Liu 已提交
4789
        Variable: Output variable with LoD specified by this layer.
Y
yangyaming 已提交
4790 4791

    Raises:
Y
Yibing Liu 已提交
4792
        ValueError: If :attr:`y` and :attr:`target_lod` are both None.
Y
yangyaming 已提交
4793 4794 4795 4796

    Examples:
        .. code-block:: python

4797
            import paddle.fluid as fluid
4798 4799 4800
            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 已提交
4801
    """
4802 4803 4804
    check_variable_and_dtype(
        x, 'x', ['float32', 'float64', 'int32', 'int64'], 'lod_reset'
    )
Y
yangyaming 已提交
4805
    helper = LayerHelper("lod_reset", **locals())
X
Xin Pan 已提交
4806
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
Y
yangyaming 已提交
4807
    if y is not None:
4808
        check_type(y, 'y', (Variable), 'lod_reset')
4809 4810 4811 4812
        # TODO: check y.lod_level = 0 dtype
        helper.append_op(
            type="lod_reset", inputs={'X': x, 'Y': y}, outputs={'Out': out}
        )
Y
yangyaming 已提交
4813
    elif target_lod is not None:
4814 4815 4816 4817 4818 4819
        helper.append_op(
            type="lod_reset",
            inputs={'X': x},
            attrs={'target_lod': target_lod},
            outputs={'Out': out},
        )
Y
yangyaming 已提交
4820
    else:
4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845
        raise ValueError("y and target_lod should not be both none.")
    return out


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

    .. code-block:: text

        * Example 1:

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

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

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

    Args:
4846
        x (Variable): Input variable which could be a tensor or LoDTensor.
4847
                      The data type should be int32, int64, float32 or float64.
4848
        level (list|tuple|Variable, optional): The LoD level to be appended into LoD of x.
4849 4850
                                               If level is variable and its lod level>0, the data type can be any type.
                                               If level is variable and its lod level=0, the data type should be int32.
4851 4852 4853 4854 4855
    Returns:
        Variable: Output variable with new LoD level.

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

4857 4858 4859 4860 4861 4862 4863 4864 4865
    Examples:
        .. code-block:: python

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

4869 4870 4871
    check_variable_and_dtype(
        x, 'x', ['float32', 'float64', 'int32', 'int64'], 'lod_append'
    )
4872

4873 4874
    helper = LayerHelper("lod_append", **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
4875 4876 4877 4878 4879 4880

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

    if isinstance(level, Variable):
        inputs['Y'] = level
4881
        # TODO: check y.lod_level = 0 dtype
4882 4883
    else:
        attrs['target_lod'] = level
4884 4885 4886
    helper.append_op(
        type="lod_reset", inputs=inputs, attrs=attrs, outputs={'Out': out}
    )
Y
yangyaming 已提交
4887
    return out
D
dragonwarrior 已提交
4888 4889


4890
def pad(x, paddings, pad_value=0.0, name=None):
4891
    r"""
4892
    :alias_main: paddle.nn.functional.pad
4893 4894
        :alias: paddle.nn.functional.pad,paddle.nn.functional.common.pad
        :old_api: paddle.fluid.layers.pad
4895

S
SunGaofeng 已提交
4896 4897
    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 已提交
4898

S
SunGaofeng 已提交
4899 4900 4901 4902
    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 已提交
4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920

    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 已提交
4921
        x (Variable): Tensor, data type is float32.
G
guosheng 已提交
4922
        paddings (list): A list of integers. Its elements specify the padded
S
SunGaofeng 已提交
4923
                         width before and after each dimension in turn.
4924
                         The length of :attr:`paddings` must be equal to
G
guosheng 已提交
4925 4926
                         :math:`rank(x) \\times 2`.
        pad_value (float): The constant value used to pad.
4927 4928
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
4929
                             For more information, please refer to :ref:`api_guide_Name`
G
guosheng 已提交
4930 4931

    Returns:
S
SunGaofeng 已提交
4932 4933 4934 4935
        The padded tensor, with the same data type and rank as :attr:`x`

    Return Type:
        Variable
G
guosheng 已提交
4936 4937 4938

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

4940
            # x is a rank 2 tensor variable
S
SunGaofeng 已提交
4941
            import paddle.fluid as fluid
4942 4943
            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 已提交
4944
    """
4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958
    check_variable_and_dtype(
        x,
        'x',
        [
            'float16',
            'float32',
            'float64',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        "pad",
    )
4959

4960 4961 4962 4963
    check_type(pad_value, 'pad_value', (float, int, Variable), 'pad')
    if isinstance(pad_value, int):
        pad_value = float(pad_value)

4964 4965
    helper = LayerHelper('pad', **locals())
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
4966
    out = helper.create_variable_for_type_inference(dtype)
4967 4968 4969 4970 4971 4972
    helper.append_op(
        type='pad',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'paddings': paddings, 'pad_value': pad_value},
    )
G
guosheng 已提交
4973
    return out
4974 4975


4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986
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',
):
4987
    """
4988

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

4991 4992
    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)
4993 4994
    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 已提交
4995
    and the resizing only applies on the three dimensions(depth, height and width).
4996

4997
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in the
4998 4999
    future and only use :attr:`out_shape` instead.

5000
    Supporting resample methods:
5001
        'LINEAR' : Linear interpolation
Q
update  
qiaolongfei 已提交
5002

5003
        'BILINEAR' : Bilinear interpolation
T
Tink_Y 已提交
5004

K
Kaipeng Deng 已提交
5005 5006
        'TRILINEAR' : Trilinear interpolation

5007
        'NEAREST' : Nearest neighbor interpolation
5008

5009
        'BICUBIC' : Bicubic interpolation
5010 5011

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

5014
    Nearest neighbor interpolation is to perform nearest neighbor interpolation
5015
    in both the 3rd dimension(in height direction) and the 4th dimension(in width
5016
    direction) on input tensor.
5017 5018 5019 5020 5021

    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
5022 5023
    again in the other direction.

5024 5025 5026
    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 已提交
5027
    The linear interpolation is performed on three directions.
5028

5029 5030 5031 5032
    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 已提交
5033

5034
    Align_corners and align_mode are optional parameters,the calculation method
5035 5036 5037 5038
    of interpolation can be selected by them.

    Example:

T
Tink_Y 已提交
5039
    .. code-block:: text
5040

T
Tink_Y 已提交
5041
        For scale:
5042

T
Tink_Y 已提交
5043
            if align_corners = True && out_size > 1 :
5044

T
Tink_Y 已提交
5045
              scale_factor = (in_size-1.0)/(out_size-1.0)
5046

T
Tink_Y 已提交
5047
            else:
5048

T
Tink_Y 已提交
5049
              scale_factor = float(in_size/out_size)
5050 5051


T
Tink_Y 已提交
5052
        Nearest neighbor interpolation:
5053

T
Tink_Y 已提交
5054 5055
          if:
              align_corners = False
5056

T
Tink_Y 已提交
5057 5058
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5059

T
Tink_Y 已提交
5060 5061
              H_out = floor (H_{in} * scale_{factor})
              W_out = floor (W_{in} * scale_{factor})
5062

T
Tink_Y 已提交
5063 5064
          else:
              align_corners = True
5065

T
Tink_Y 已提交
5066 5067
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5068

T
Tink_Y 已提交
5069 5070
              H_out = round(H_{in} * scale_{factor})
              W_out = round(W_{in} * scale_{factor})
5071

5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088
        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 已提交
5089 5090 5091 5092
        Bilinear interpolation:

          if:
              align_corners = False , align_mode = 0
5093

T
Tink_Y 已提交
5094 5095
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5096

T
Tink_Y 已提交
5097 5098
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5
5099

T
Tink_Y 已提交
5100
          else:
5101

T
Tink_Y 已提交
5102 5103
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5104

T
Tink_Y 已提交
5105 5106
              H_out = H_{in} * scale_{factor}
              W_out = W_{in} * scale_{factor}
5107

K
Kaipeng Deng 已提交
5108 5109 5110 5111
        Trilinear interpolation:

          if:
              align_corners = False , align_mode = 0
5112

K
Kaipeng Deng 已提交
5113 5114
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:
5115

K
Kaipeng Deng 已提交
5116 5117 5118 5119 5120 5121
              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:
5122

K
Kaipeng Deng 已提交
5123 5124 5125 5126
              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}
5127

5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139
        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 已提交
5140 5141
              H_out = H_{in} * scale_{factor}
              W_out = W_{in} * scale_{factor}
5142

5143

5144 5145
    For details of linear interpolation, please refer to Wikipedia:
    https://en.wikipedia.org/wiki/Linear_interpolation.
5146

5147
    For details of nearest neighbor interpolation, please refer to Wikipedia:
5148
    https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation.
5149

5150
    For details of bilinear interpolation, please refer to Wikipedia:
5151
    https://en.wikipedia.org/wiki/Bilinear_interpolation.
5152

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

5156 5157
    For details of bicubic interpolation, please refer to Wikipedia:
    https://en.wikipedia.org/wiki/Bicubic_interpolation
5158

R
ruri 已提交
5159
    Parameters:
5160
        input (Variable): 3-D, 4-D or 5-D Tensor, its data type is float32, float64, or uint8,
5161
                          its data format is specified by :attr:`data_format`.
5162
        out_shape (list|tuple|Variable|None): Output shape of image resize
5163 5164
             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.
5165
             Default: None. If a list, each element can be an integer or a Tensor Variable of shape: [1].
5166
             If a Tensor Variable, its dimensions size should be a 1.
5167 5168 5169
        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 已提交
5170
             Default: None.
5171 5172
        name(str|None): A name for this layer(optional). If set None, the layer
                        will be named automatically.
5173
        resample(str): The resample method. It supports 'LINEAR', 'BICUBIC', 'BILINEAR', 'TRILINEAR'
K
Kaipeng Deng 已提交
5174
                       and 'NEAREST' currently. Default: 'BILINEAR'
5175 5176 5177
        actual_shape(Variable): An optional input to specify output shape
                                dynamically. If provided, image resize
                                according to this given shape rather than
5178
                                :attr:`out_shape` and :attr:`scale` specifying
5179 5180
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
5181 5182 5183 5184 5185
                                :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 已提交
5186
                                errors would be occurred in graph constructing stage.
5187
                                Default: None
5188 5189
        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
5190 5191
                               corner pixels.
                               Default: True
5192 5193
        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 ,
5194
                            can be \'1\' for src_idx = scale*dst_index.
5195
        data_format (str, optional): Specify the data format of the input, and the data format of the output
5196
            will be consistent with that of the input. An optional string from:`NCW`, `NWC`, `"NCHW"`, `"NHWC"`, `"NCDHW"`,
5197
            `"NDHWC"`. The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
5198
            `[batch_size, input_channels, input_height, input_width]`. When it is `"NCHW"`, the data is stored
5199
            in the order of: `[batch_size, input_channels, input_depth, input_height, input_width]`.
5200 5201

    Returns:
5202
        A 3-D Tensor of the shape (num_batches, channels, out_w) or (num_batches, out_w, channels),
5203 5204
        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 已提交
5205

5206 5207 5208
    Raises:
        TypeError: out_shape should be a list or tuple or Variable.
        TypeError: actual_shape should either be Variable or None.
5209 5210
        ValueError: The 'resample' of image_resize can only be 'LINEAR', 'BILINEAR',
                    'TRILINEAR', 'BICUBIC' or 'NEAREST' currently.
5211
        ValueError: 'LINEAR' only support 3-D tensor.
5212
        ValueError: 'BICUBIC', 'BILINEAR' and 'NEAREST' only support 4-D tensor.
K
Kaipeng Deng 已提交
5213
        ValueError: 'TRILINEAR' only support 5-D tensor.
5214
        ValueError: One of out_shape and scale must not be None.
5215
        ValueError: out_shape length should be 1 for input 3-D tensor.
K
Kaipeng Deng 已提交
5216 5217
        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 已提交
5218
        ValueError: scale should be greater than zero.
T
tianshuo78520a 已提交
5219
        TypeError: align_corners should be a bool value
5220
        ValueError: align_mode can only be '0' or '1'
5221
        ValueError: data_format can only be 'NCW', 'NWC', 'NCHW', 'NHWC', 'NCDHW' or 'NDHWC'.
5222

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

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

5233 5234
            #1
            output = fluid.layers.image_resize(input=input,out_shape=[12,12])
R
ruri 已提交
5235

5236 5237 5238 5239 5240
            #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 已提交
5241

5242 5243 5244 5245 5246
            #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 已提交
5247

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

5254 5255 5256
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5257

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

5260
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
5261 5262 5263
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
5264

5265
            print(output_data[0].shape)
5266

5267 5268 5269 5270 5271 5272 5273 5274
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
5275

5276 5277
            #imperative mode
            import paddle.fluid.dygraph as dg
5278

5279 5280 5281 5282
            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)
5283

5284
                # [2L, 3L, 12L, 12L]
5285

5286
    """
5287
    resample_methods = {
5288
        'LINEAR': 'linear',
5289
        'BILINEAR': 'bilinear',
K
Kaipeng Deng 已提交
5290
        'TRILINEAR': 'trilinear',
5291
        'NEAREST': 'nearest',
5292
        'LINEAR': 'linear',
5293
    }
5294
    resample = resample.upper()
5295 5296
    if resample not in resample_methods:
        raise ValueError(
5297
            "The 'resample' of image_resize can only be 'LINEAR', 'BILINEAR', 'TRILINEAR' "
5298 5299
            "or 'NEAREST' currently."
        )
5300
    resample_type = resample_methods[resample]
5301

5302 5303 5304
    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 已提交
5305
        raise ValueError("'BILINEAR' and 'NEAREST' only support 4-D tensor.")
5306
    elif resample == 'TRILINEAR' and len(input.shape) != 5:
K
Kaipeng Deng 已提交
5307 5308
        raise ValueError("'TRILINEAR'only support 5-D tensor.")

5309 5310 5311 5312 5313
    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")

5314
    if out_shape is None and scale is None:
5315
        raise ValueError("One of out_shape and scale must not be None.")
5316
    helper = LayerHelper('{}_interp'.format(resample_type), **locals())
5317
    dtype = helper.input_dtype()
5318

5319
    if len(input.shape) == 3 and data_format not in ['NCW', 'NWC']:
5320
        raise ValueError(
5321 5322 5323 5324
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCW` or `NWC` supported for 3-D input."
        )
5325
    elif len(input.shape) == 4 and data_format not in ['NCHW', 'NHWC']:
5326
        raise ValueError(
5327 5328 5329 5330
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCHW` or `NHWC` supported for 4-D input."
        )
5331 5332
    elif len(input.shape) == 5 and data_format not in ['NCDHW', 'NDHWC']:
        raise ValueError(
5333 5334 5335 5336
            "Got wrong value for param `data_format`: "
            + data_format
            + " received but only `NCDHW` or `NDHWC` supported for 5-D input."
        )
5337

5338
    def _is_list_or_turple_(data):
5339
        return isinstance(data, list) or isinstance(data, tuple)
5340

5341
    if data_format == 'NCHW' or data_format == 'NCDHW' or data_format == 'NCW':
5342
        data_layout = 'NCHW'
5343
    if data_format == 'NHWC' or data_format == 'NDHWC' or data_format == 'NWC':
5344 5345
        data_layout = 'NHWC'

5346
    inputs = {"X": input}
D
dengkaipeng 已提交
5347
    attrs = {
5348 5349 5350
        "out_d": -1,
        "out_h": -1,
        "out_w": -1,
D
dengkaipeng 已提交
5351 5352
        "interp_method": resample_type,
        "align_corners": align_corners,
5353
        "align_mode": align_mode,
5354
        "data_layout": data_layout,
D
dengkaipeng 已提交
5355 5356
    }

5357
    if out_shape is not None:
5358
        if isinstance(out_shape, Variable) and not _non_static_mode():
5359
            out_shape.stop_gradient = True
5360
            inputs['OutSize'] = out_shape
5361
        else:
5362 5363 5364 5365 5366 5367 5368 5369
            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]
5370
            if not (_is_list_or_turple_(out_shape)):
D
dengkaipeng 已提交
5371
                raise TypeError(
5372 5373
                    "out_shape should be a list or tuple or Variable."
                )
5374 5375 5376 5377 5378 5379
            # Validate the shape
            contain_var = False
            for dim_idx, dim_size in enumerate(out_shape):
                if isinstance(dim_size, Variable):
                    contain_var = True
                    continue
5380 5381 5382
                assert (
                    dim_size > 0
                ), "Each dimension size given in out_shape must be greater than 0."
5383 5384 5385 5386 5387 5388 5389 5390 5391 5392

            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:
5393
                        assert isinstance(dim, int)
5394
                        temp_out = helper.create_variable_for_type_inference(
5395 5396 5397 5398 5399
                            'int32'
                        )
                        fill_constant(
                            [1], 'int32', dim, force_cpu=True, out=temp_out
                        )
5400 5401 5402 5403
                        new_size_tensor.append(temp_out)
                        size_list.append(dim)
                inputs['SizeTensor'] = new_size_tensor

5404 5405
            if len(input.shape) == 3:
                if len(out_shape) != 1:
5406 5407 5408
                    raise ValueError(
                        "out_shape length should be 1 for " "input 3-D tensor."
                    )
5409 5410 5411 5412 5413 5414
                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 已提交
5415
                if len(out_shape) != 2:
5416 5417 5418
                    raise ValueError(
                        "out_shape length should be 2 for " "input 4-D tensor."
                    )
5419 5420 5421 5422 5423 5424 5425
                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 已提交
5426 5427
            if len(input.shape) == 5:
                if len(out_shape) != 3:
5428 5429 5430
                    raise ValueError(
                        "out_shape length should be 3 for " "input 5-D tensor."
                    )
5431 5432 5433 5434 5435 5436 5437 5438 5439
                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]
5440

5441
    else:
5442 5443 5444
        if _non_static_mode() and isinstance(scale, Variable):
            scale = scale.numpy()
        elif isinstance(scale, Variable):
5445 5446
            scale.stop_gradient = True
            inputs["Scale"] = scale
5447
        elif isinstance(scale, float) or isinstance(scale, int):
5448
            if scale <= 0:
5449
                raise ValueError("Attr(scale) should be greater than zero.")
5450
            attrs['scale'] = float(scale)
5451 5452
        else:
            raise TypeError(
5453 5454
                "Attr(scale)'s type should be float, int or Variable."
            )
5455

5456
    if isinstance(actual_shape, Variable):
5457 5458 5459 5460 5461
        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
5462 5463 5464
        inputs["OutSize"] = actual_shape
    elif actual_shape is not None:
        raise TypeError("actual_shape should either be Variable or None.")
5465 5466 5467 5468 5469 5470 5471 5472 5473

    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":
5474
            out = _legacy_C_ops.linear_interp(input, actual_shape, *dy_attr)
5475
        elif resample_type == "bilinear":
5476
            out = _legacy_C_ops.bilinear_interp(input, actual_shape, *dy_attr)
5477
        elif resample_type == "trilinear":
5478
            out = _legacy_C_ops.trilinear_interp(input, actual_shape, *dy_attr)
5479
        elif resample_type == "nearest":
5480
            out = _legacy_C_ops.nearest_interp(input, actual_shape, *dy_attr)
5481
        elif resample_type == "bicubic":
5482
            out = _legacy_C_ops.bicubic_interp(input, actual_shape, *dy_attr)
5483 5484
        return out

X
Xin Pan 已提交
5485
    out = helper.create_variable_for_type_inference(dtype)
5486 5487 5488 5489 5490 5491
    helper.append_op(
        type='{}_interp'.format(resample_type),
        inputs=inputs,
        outputs={"Out": out},
        attrs=attrs,
    )
5492
    return out
F
stash  
fengjiayi 已提交
5493 5494


5495
@templatedoc(op_type="bilinear_interp")
5496 5497 5498 5499 5500 5501 5502 5503 5504 5505
def resize_bilinear(
    input,
    out_shape=None,
    scale=None,
    name=None,
    actual_shape=None,
    align_corners=True,
    align_mode=1,
    data_format='NCHW',
):
5506
    """
5507

R
ruri 已提交
5508
    This op resizes the input by performing bilinear interpolation based on given
5509
    output shape which specified by actual_shape, out_shape and scale
5510 5511
    in priority order.

5512
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in
5513 5514
    the future and only use :attr:`out_shape` instead.

5515 5516 5517 5518
    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
5519 5520
    again in the other direction.

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

5524
    Align_corners and align_mode are optional parameters,the calculation
5525 5526 5527 5528
    method of interpolation can be selected by them.

    Example:

T
Tink_Y 已提交
5529
    .. code-block:: text
5530

T
Tink_Y 已提交
5531
        For scale:
5532

T
Tink_Y 已提交
5533
            if align_corners = True && out_size > 1 :
5534

T
Tink_Y 已提交
5535
              scale_factor = (in_size-1.0)/(out_size-1.0)
5536

T
Tink_Y 已提交
5537
            else:
5538

5539
              scale_factor = float(in_size/out_size)
5540

T
Tink_Y 已提交
5541 5542 5543 5544
        Bilinear interpolation:

          if:
              align_corners = False , align_mode = 0
5545

T
Tink_Y 已提交
5546 5547
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5548

T
Tink_Y 已提交
5549 5550
              H_out = (H_{in}+0.5) * scale_{factor} - 0.5
              W_out = (W_{in}+0.5) * scale_{factor} - 0.5
5551

T
Tink_Y 已提交
5552
          else:
T
tink2123 已提交
5553

T
Tink_Y 已提交
5554 5555 5556 5557
              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}
5558

R
ruri 已提交
5559 5560
    Parameters:
        input(Variable): 4-D Tensor(NCHW), its data type is float32, float64, or uint8,
5561
                          its data format is specified by :attr:`data_format`.
D
dengkaipeng 已提交
5562
        out_shape(list|tuple|Variable|None): Output shape of resize bilinear
5563 5564
            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
5565
            Tensor Variable, its dimension size should be 1.
5566
        scale(float|Variable|None): The multiplier for the input height or width. At
5567 5568
             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 已提交
5569
             Default: None.
5570 5571 5572
        actual_shape(Variable): An optional input to specify output shape
                                dynamically. If provided, image resize
                                according to this given shape rather than
5573
                                :attr:`out_shape` and :attr:`scale` specifying
5574 5575
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
5576 5577 5578 5579 5580
                                :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 已提交
5581
                                errors would be occurred in graph constructing stage.
5582
                                Default: None
5583 5584
        align_corners(bool): ${align_corners_comment}
        align_mode(bool): ${align_mode_comment}
5585
        data_format (str, optional): Specify the data format of the input, and the data format of the output
5586 5587 5588
            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 已提交
5589
        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 已提交
5590 5591

    Returns:
5592
        Variable: 4-D tensor(NCHW or NHWC).
5593

5594 5595
    Examples:
        .. code-block:: python
5596

5597 5598 5599 5600 5601 5602
            #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 已提交
5603

5604 5605
            #1
            output = fluid.layers.resize_bilinear(input=input,out_shape=[12,12])
R
ruri 已提交
5606

5607 5608 5609 5610 5611
            #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 已提交
5612

5613 5614 5615 5616 5617
            #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 已提交
5618

5619 5620 5621 5622 5623
            #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 已提交
5624

5625 5626 5627
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5628

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

5631
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
5632 5633 5634
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
5635

5636
            print(output_data[0].shape)
5637

5638 5639 5640 5641 5642 5643 5644 5645
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
5646

5647 5648
            #imperative mode
            import paddle.fluid.dygraph as dg
5649

5650 5651 5652 5653
            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)
5654

5655
                # [2L, 3L, 12L, 12L]
5656

5657 5658
    """

5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'BILINEAR',
        actual_shape,
        align_corners,
        align_mode,
        data_format,
    )
5670 5671


K
Kaipeng Deng 已提交
5672
@templatedoc(op_type="trilinear_interp")
5673 5674 5675 5676 5677 5678 5679 5680 5681 5682
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 已提交
5683
    """
5684

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

5689
    **Warning:** the parameter :attr:`actual_shape` will be deprecated
5690 5691
    in the future and only use :attr:`out_shape` instead.

5692 5693 5694
    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 已提交
5695 5696 5697 5698 5699
    The linear interpolation is performed on three directions.

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

5700
    Align_corners and align_mode are optional parameters,the calculation
K
Kaipeng Deng 已提交
5701 5702 5703 5704 5705 5706 5707
    method of interpolation can be selected by them.

    Example:

    .. code-block:: text

        For scale:
5708

K
Kaipeng Deng 已提交
5709 5710 5711
            if align_corners = True && out_size > 1 :

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

K
Kaipeng Deng 已提交
5713
            else:
5714 5715

              scale_factor = float(in_size/out_size)
K
Kaipeng Deng 已提交
5716 5717 5718 5719

        Bilinear interpolation:

          if:
5720

K
Kaipeng Deng 已提交
5721
              align_corners = False , align_mode = 0
5722

K
Kaipeng Deng 已提交
5723 5724
              input : (N,C,D_in,H_in,W_in)
              output: (N,C,D_out,H_out,W_out) where:
5725

K
Kaipeng Deng 已提交
5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738
              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 已提交
5739
    Parameters:
5740 5741
        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 已提交
5742
        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.
5743
        scale(float|Variable|None): The multiplier for the input depth, height or width.
5744 5745
             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 已提交
5746
             Default: None.
R
ruri 已提交
5747
        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 已提交
5748 5749 5750 5751 5752 5753
        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
5754 5755 5756 5757 5758
                                :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 已提交
5759
                                errors would be occurred in graph constructing stage.
K
Kaipeng Deng 已提交
5760 5761 5762
                                Default: None
        align_corners(bool): ${align_corners_comment}
        align_mode(bool): ${align_mode_comment}
5763
        data_format (str, optional): Specify the data format of the input, and the data format of the output
5764 5765 5766
            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 已提交
5767 5768

    Returns:
5769
        Variable: A 5-D Tensor(NCDHW or NDHWC)
K
Kaipeng Deng 已提交
5770 5771 5772

    Examples:
        .. code-block:: python
5773

5774 5775 5776 5777 5778 5779
            #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 已提交
5780

5781 5782
            #1
            output = fluid.layers.resize_trilinear(input=input,out_shape=[12,12,12])
R
ruri 已提交
5783

5784 5785 5786 5787 5788
            #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 已提交
5789

5790 5791 5792 5793 5794
            #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 已提交
5795

5796 5797 5798 5799 5800
            #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 已提交
5801

5802 5803 5804
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5805

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

5808
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
5809 5810 5811
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
5812

5813
            print(output_data[0].shape)
R
ruri 已提交
5814

5815 5816 5817 5818 5819 5820 5821 5822
            #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 已提交
5823

5824 5825
            #imperative mode
            import paddle.fluid.dygraph as dg
5826

5827 5828 5829 5830
            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)
5831

5832
                # [2L, 3L, 12L, 12L, 12L]
5833 5834 5835



K
Kaipeng Deng 已提交
5836 5837
    """

5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'TRILINEAR',
        actual_shape,
        align_corners,
        align_mode,
        data_format,
    )
K
Kaipeng Deng 已提交
5849 5850


5851
@templatedoc(op_type="nearest_interp")
5852 5853 5854 5855 5856 5857 5858 5859 5860
def resize_nearest(
    input,
    out_shape=None,
    scale=None,
    name=None,
    actual_shape=None,
    align_corners=True,
    data_format='NCHW',
):
5861
    """
5862

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

5867
    **Warning:** the parameter :attr:`actual_shape` will be deprecated in the
5868 5869
    future and only use :attr:`out_shape` instead.

5870 5871
    Example:

T
Tink_Y 已提交
5872 5873 5874
    .. code-block:: text

        For scale:
5875

T
Tink_Y 已提交
5876 5877
            if align_corners = True && out_size > 1 :
              scale_factor = (in_size-1.0)/(out_size-1.0)
5878

T
Tink_Y 已提交
5879
            else:
5880

T
Tink_Y 已提交
5881
              scale_factor = float(in_size/out_size)
5882

T
Tink_Y 已提交
5883
        Nearest neighbor interpolation:
5884

T
Tink_Y 已提交
5885 5886
          if:
              align_corners = False
5887

T
Tink_Y 已提交
5888 5889
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5890

T
Tink_Y 已提交
5891 5892
              H_out = floor(H_{in} * scale_{factor})
              W_out = floor(W_{in} * scale_{factor})
5893

T
Tink_Y 已提交
5894 5895
          else:
              align_corners = True
5896

T
Tink_Y 已提交
5897 5898
              input : (N,C,H_in,W_in)
              output: (N,C,H_out,W_out) where:
5899

T
Tink_Y 已提交
5900 5901
              H_out = round(H_{in} * scale_{factor})
              W_out = round(W_{in} * scale_{factor})
5902 5903


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

R
ruri 已提交
5907
    Parameters:
5908 5909
        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 已提交
5910
        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.
5911
        scale(float|Variable|None): The multiplier for the input height or width. At
5912 5913 5914
             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 已提交
5915
        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`
5916
        actual_shape(Variable): An optional input to specify output shape
5917 5918
                                dynamically. If provided, image resize
                                according to this given shape rather than
5919
                                :attr:`out_shape` and :attr:`scale` specifying
5920 5921
                                shape. That is to say actual_shape has the
                                highest priority. It is recommended to use
5922 5923 5924 5925 5926
                                :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 已提交
5927
                                errors would be occurred in graph constructing stage.
5928
                                Default: None
5929
        align_corners(bool): ${align_corners_comment}
5930
        data_format (str, optional): Specify the data format of the input, and the data format of the output
5931 5932 5933
            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 已提交
5934 5935

    Returns:
5936
        Variable: 4-D tensor(NCHW or NHWC).
5937 5938 5939

    Examples:
        .. code-block:: python
5940

5941 5942 5943 5944 5945
            #declarative mode
            import paddle.fluid as fluid
            import numpy as np
            import paddle
            paddle.enable_static()
5946

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

5949 5950
            #1
            output = fluid.layers.resize_nearest(input=input,out_shape=[12,12])
R
ruri 已提交
5951

5952 5953 5954 5955 5956
            #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 已提交
5957

5958 5959 5960 5961 5962
            #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 已提交
5963

5964 5965 5966 5967 5968
            #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 已提交
5969

5970 5971 5972
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5973

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

5976
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
5977 5978 5979
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
5980

5981
            print(output_data[0].shape)
R
ruri 已提交
5982

5983 5984 5985 5986 5987 5988 5989 5990
            #1
            # (2, 3, 12, 12)
            #2
            # (2, 3, 12, 2)
            #3
            # (2, 3, 3, 12)
            #4
            # (2, 3, 3, 5)
5991

5992 5993
            #imperative mode
            import paddle.fluid.dygraph as dg
5994

5995 5996 5997 5998
            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 已提交
5999

6000
                # [2L, 3L, 12L, 12L]
6001 6002 6003



6004 6005
    """

6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016
    return image_resize(
        input,
        out_shape,
        scale,
        name,
        'NEAREST',
        actual_shape,
        align_corners,
        align_mode=1,
        data_format=data_format,
    )
6017 6018


6019
def log(x, name=None):
6020
    r"""
W
wanghaoshuang 已提交
6021 6022 6023 6024
    Calculates the natural log of the given input tensor, element-wise.

    .. math::

6025
        Out = \\ln(x)
W
wanghaoshuang 已提交
6026 6027

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

W
wanghaoshuang 已提交
6031 6032

    Returns:
S
Steffy-zxf 已提交
6033
        Tensor: The natural log of the input Tensor computed element-wise.
W
wanghaoshuang 已提交
6034 6035 6036 6037 6038

    Examples:

        .. code-block:: python

S
Steffy-zxf 已提交
6039
            import paddle
W
Wilber 已提交
6040

S
Steffy-zxf 已提交
6041 6042 6043 6044
            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 已提交
6045
    """
6046
    if in_dygraph_mode():
W
wanghuancoder 已提交
6047
        return _C_ops.log(x)
6048 6049
    if _in_legacy_dygraph():
        return _legacy_C_ops.log(x)
6050

6051
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], "log")
6052
    inputs = {'X': [x]}
W
wanghaoshuang 已提交
6053
    helper = LayerHelper('log', **locals())
W
wanghaoshuang 已提交
6054
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
6055
    out = helper.create_variable_for_type_inference(dtype)
W
wanghaoshuang 已提交
6056
    helper.append_op(type="log", inputs={"X": x}, outputs={"Out": out})
W
wanghaoshuang 已提交
6057 6058 6059
    return out


6060
@deprecated(since="2.0.0", update_to="paddle.nn.functional.relu")
6061
def relu(x, name=None):
W
wanghaoshuang 已提交
6062
    """
Z
zhupengyang 已提交
6063
    ${comment}
W
wanghaoshuang 已提交
6064 6065

    Args:
Z
zhupengyang 已提交
6066 6067 6068 6069
        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 已提交
6070 6071

    Returns:
Z
zhupengyang 已提交
6072
        Variable: ${out_comment}
W
wanghaoshuang 已提交
6073 6074 6075 6076 6077

    Examples:

        .. code-block:: python

6078
            import paddle.fluid as fluid
Z
zhupengyang 已提交
6079 6080 6081 6082 6083 6084 6085
            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. ]
6086
                #  [1.  2.6]]"""
6087 6088

    if in_dygraph_mode():
W
wanghuancoder 已提交
6089
        return _C_ops.relu(x)
6090 6091
    if _in_legacy_dygraph():
        return _legacy_C_ops.relu(x)
6092

6093 6094
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'relu')

6095
    inputs = {'X': [x]}
W
wanghaoshuang 已提交
6096
    helper = LayerHelper('relu', **locals())
W
wanghaoshuang 已提交
6097
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
6098
    out = helper.create_variable_for_type_inference(dtype)
6099 6100 6101
    helper.append_op(
        type="relu", inputs={"X": helper.input('x')}, outputs={"Out": out}
    )
W
wanghaoshuang 已提交
6102
    return out
6103 6104


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

Z
zhupengyang 已提交
6109
    prelu activation.
J
jerrywgz 已提交
6110

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

J
jerrywgz 已提交
6114 6115 6116 6117 6118 6119 6120 6121
    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 已提交
6122 6123
    Parameters:
        x (Tensor): The input Tensor or LoDTensor with data type float32.
6124
        mode (str): The mode for weight sharing.
U
ustiniankw 已提交
6125 6126 6127
        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`.
6128 6129
        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 已提交
6130 6131
        name (str, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.
J
jerrywgz 已提交
6132 6133

    Returns:
U
ustiniankw 已提交
6134
        Tensor, A tensor with the same shape and data type as x.
J
jerrywgz 已提交
6135 6136 6137 6138

    Examples:
        .. code-block:: python

6139
            import paddle
Z
zhupengyang 已提交
6140 6141 6142 6143 6144

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

J
jerrywgz 已提交
6146
    """
G
Guoxia Wang 已提交
6147
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'prelu')
6148

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

J
jerrywgz 已提交
6153 6154
    alpha_shape = [1]
    if mode == 'channel':
6155 6156

        true_data_format = [
6157 6158 6159 6160 6161 6162 6163
            'NC',
            'NCL',
            'NCHW',
            'NCDHW',
            'NLC',
            'NHWC',
            'NDHWC',
6164 6165 6166 6167
        ]
        if data_format not in true_data_format:
            raise ValueError(
                "data_format must be one of 'NC', 'NCL', 'NCHW', 'NCDHW', "
6168 6169
                "'NLC', 'NHWC', 'NDHWC' but receive {}".format(data_format)
            )
6170 6171 6172

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

6173 6174 6175 6176
        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:]).
6177
        # To be consistent with Prelu, it is simplified.
6178 6179
        # NOTE(zhiqiu): Revert shape to [1, channel, 1, 1] for compatibility with saved model of old version.
        # NOTE(GuoxiaWang): support NHWC data format
6180
        if data_format == 'NHWC':
6181
            alpha_shape = [1, 1, 1, x.shape[-1]]
6182 6183 6184
        else:
            alpha_shape = [1, x.shape[1], 1, 1]

J
jerrywgz 已提交
6185
    elif mode == 'element':
6186 6187 6188
        assert (
            len(x.shape) >= 1
        ), "The size of input shape should be equal or larger than 1 in prelu() when mode is 'element'"
6189
        alpha_shape = [1] + list(x.shape)[1:]
J
jerrywgz 已提交
6190
    dtype = helper.input_dtype(input_param_name='x')
6191 6192 6193 6194 6195 6196 6197
    alpha = helper.create_parameter(
        attr=helper.param_attr,
        shape=alpha_shape,
        dtype=dtype,
        is_bias=False,
        default_initializer=Constant(0.25),
    )
6198 6199 6200
    if in_dygraph_mode():
        return _C_ops.prelu(x, alpha, data_format, mode)

X
Xin Pan 已提交
6201
    out = helper.create_variable_for_type_inference(dtype)
6202 6203 6204 6205 6206 6207
    helper.append_op(
        type="prelu",
        inputs={"X": x, 'Alpha': alpha},
        attrs={"mode": mode, "data_format": data_format},
        outputs={"Out": out},
    )
6208 6209 6210
    return out


G
fix  
gongweibao 已提交
6211 6212 6213
from paddle.fluid.framework import convert_np_dtype_to_dtype_


6214
@deprecated(since="2.0.0", update_to="paddle.normal")
G
gongweibao 已提交
6215
@templatedoc()
6216 6217 6218
def gaussian_random(
    shape, mean=0.0, std=1.0, seed=0, dtype='float32', name=None
):
G
fix  
gongweibao 已提交
6219
    """
6220 6221
    This OP returns a Tensor filled with random values sampled from a Gaussian
    distribution, with ``shape`` and ``dtype``.
G
fix  
gongweibao 已提交
6222 6223

    Args:
6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238
        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 已提交
6239 6240

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

6244
    Examples:
6245
       .. code-block:: python
6246

6247
            import paddle
6248
            import paddle.fluid as fluid
6249
            paddle.enable_static()
6250 6251

            # example 1:
6252
            # attr shape is a list which doesn't contain Tensor.
6253
            result_1 = fluid.layers.gaussian_random(shape=[3, 4])
6254 6255 6256
            # [[-0.31261674,  1.8736548,  -0.6274357,   0.96988016],
            #  [-0.12294637,  0.9554768,   1.5690808,  -1.2894802 ],
            #  [-0.60082096, -0.61138713,  1.5345167,  -0.21834975]]
6257 6258

            # example 2:
6259 6260 6261
            # 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)
6262
            result_2 = fluid.layers.gaussian_random(shape=[dim_1, dim_2])
6263 6264
            # [[ 0.51398206, -0.3389769,   0.23597084],
            #  [ 1.0388143,  -1.2015356,  -1.0499583 ]]
6265 6266

            # example 3:
6267
            # attr shape is a Tensor, the data type must be int64 or int32.
6268 6269
            var_shape = fluid.data(name='var_shape', shape=[2], dtype="int64")
            result_3 = fluid.layers.gaussian_random(var_shape)
6270 6271 6272 6273
            # if var_shape's value is [2, 3]
            # result_3 is:
            # [[-0.12310527,  0.8187662,   1.923219  ]
            #  [ 0.70721835,  0.5210541,  -0.03214082]]
6274

6275
       .. code-block:: python
6276

6277 6278
           # declarative mode
           # required: skiptest
6279 6280
           import numpy as np
           from paddle import fluid
6281

6282
           x = fluid.layers.gaussian_random((2, 3), std=2., seed=10)
6283

6284 6285 6286 6287
           place = fluid.CPUPlace()
           exe = fluid.Executor(place)
           start = fluid.default_startup_program()
           main = fluid.default_main_program()
6288

6289 6290
           exe.run(start)
           x_np, = exe.run(main, feed={}, fetch_list=[x])
6291

6292 6293 6294 6295 6296 6297 6298 6299 6300 6301
           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
6302

6303 6304 6305
           place = fluid.CPUPlace()
           with dg.guard(place) as g:
               x = fluid.layers.gaussian_random((2, 4), mean=2., dtype="float32", seed=10)
6306
               x_np = x.numpy()
6307 6308 6309
           x_np
           # array([[2.3060477 , 2.676496  , 3.9911983 , 0.9990833 ],
           #        [2.8675377 , 2.2279181 , 0.79029655, 2.8447366 ]], dtype=float32)
G
fix  
gongweibao 已提交
6310
    """
6311 6312
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
6313

6314 6315 6316
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
        place = _current_expected_place()
6317
        return _C_ops.gaussian(
6318 6319
            shape, float(mean), float(std), seed, dtype, place
        )
6320 6321

    if _in_legacy_dygraph():
6322
        shape = utils.convert_shape_to_list(shape)
6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334
        return _legacy_C_ops.gaussian_random(
            'shape',
            shape,
            'mean',
            float(mean),
            'std',
            float(std),
            'seed',
            seed,
            'dtype',
            dtype,
        )
6335 6336 6337

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

    inputs = {}
6340 6341 6342 6343
    attrs = {
        'mean': mean,
        'std': std,
        'seed': seed,
6344
        'dtype': dtype,
6345
        'use_mkldnn': False,
6346
    }
6347 6348 6349
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='gaussian_random/randn'
    )
6350

6351 6352
    helper = LayerHelper('gaussian_random', **locals())
    out = helper.create_variable_for_type_inference(dtype)
6353 6354 6355
    helper.append_op(
        type='gaussian_random', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
G
fix  
gongweibao 已提交
6356 6357 6358 6359

    return out


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

R
ruri 已提交
6365 6366 6367 6368
    Parameters:
        x (Variable): 2-D tensor, [batch_size, input_feature_dimensions]
        min (Float): minimum , default 0.0.
        max (Float): maximum, default 1.0.
6369
        seed (Float): Random seed, default 0. if seed is not 0, will generate same number every time.
G
fix  
gongweibao 已提交
6370
        dtype(np.dtype|core.VarDesc.VarType|str): The type of output data : float32, float_16, int etc
G
fix  
gongweibao 已提交
6371 6372

    Returns:
R
ruri 已提交
6373
        Variable: sampling tensor.
G
fix  
gongweibao 已提交
6374

6375 6376 6377
    Examples:
        .. code-block:: python

6378
            import paddle.fluid as fluid
R
ruri 已提交
6379
            x = fluid.data(
6380 6381
                name="X",
                shape=[13, 11],
R
ruri 已提交
6382
                dtype='float32')
6383

Y
Yibing Liu 已提交
6384
            out = fluid.layers.sampling_id(x)
G
fix  
gongweibao 已提交
6385 6386 6387
    """

    helper = LayerHelper('sampling_id', **locals())
X
Xin Pan 已提交
6388
    out = helper.create_variable_for_type_inference(dtype)
6389 6390 6391 6392 6393 6394
    helper.append_op(
        type='sampling_id',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'min': min, 'max': max, 'seed': seed},
    )
G
fix  
gongweibao 已提交
6395 6396 6397 6398

    return out


G
gongweibao 已提交
6399
@templatedoc()
X
Xin Pan 已提交
6400
def sum(x):
G
fix  
gongweibao 已提交
6401
    """
G
gongweibao 已提交
6402
    ${comment}
6403

6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432
    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 已提交
6433 6434

    Args:
6435
        x (Variable|list(Variable)): ${x_comment}
G
fix  
gongweibao 已提交
6436 6437

    Returns:
6438
        Variable: ${out_comment}
6439 6440 6441 6442

    Examples:
        .. code-block:: python

6443
            import paddle.fluid as fluid
6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462

            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.
6463 6464
            # 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,
6465
            #       and '__int64' on Windows. They both represent 64-bit integer variables.
G
fix  
gongweibao 已提交
6466 6467
    """

S
Steffy-zxf 已提交
6468
    return paddle.add_n(x)
G
fix  
gongweibao 已提交
6469 6470


G
gongweibao 已提交
6471
@templatedoc()
G
fix  
gongweibao 已提交
6472 6473
def slice(input, axes, starts, ends):
    """
6474
    This operator produces a slice of ``input`` along multiple axes. Similar to numpy:
6475
    https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html
6476 6477 6478 6479 6480 6481 6482
    Slice uses ``axes``, ``starts`` and ``ends`` attributes to specify the start and
    end dimension for each axis in the list of axes and Slice uses this information
    to slice the input data tensor. If a negative value is passed to
    ``starts`` or ``ends`` such as :math:`-i`,  it represents the reverse position of the
    axis :math:`i-1` (here 0 is the initial position).
    If the value passed to ``starts`` or ``ends`` is greater than n
    (the number of elements in this dimension), it represents n.
6483
    For slicing to the end of a dimension with unknown size, it is recommended
6484
    to pass in INT_MAX. The size of ``axes`` must be equal to ``starts`` and ``ends``.
6485 6486 6487
    Following examples will explain how slice works:

    .. code-block:: text
G
fix  
gongweibao 已提交
6488

6489 6490 6491 6492 6493 6494 6495 6496
        Case1:
            Given:
                data = [ [1, 2, 3, 4], [5, 6, 7, 8], ]
                axes = [0, 1]
                starts = [1, 0]
                ends = [2, 3]
            Then:
                result = [ [5, 6, 7], ]
6497

6498 6499 6500 6501 6502
        Case2:
            Given:
                data = [ [1, 2, 3, 4], [5, 6, 7, 8], ]
                axes = [0, 1]
                starts = [0, 1]
6503
                ends = [-1, 1000]       # -1 denotes the reverse 0th position of dimension 0.
6504
            Then:
6505
                result = [ [2, 3, 4], ] # result = data[0:1, 1:4]
6506

G
fix  
gongweibao 已提交
6507
    Args:
T
Thunderbrook 已提交
6508
        input (Tensor): A ``Tensor`` . The data type is ``float16``, ``float32``, ``float64``, ``int32`` or ``int64``.
6509
        axes (list|tuple): The data type is ``int32`` . Axes that `starts` and `ends` apply to .
T
Thunderbrook 已提交
6510 6511
        starts (list|tuple|Tensor): The data type is ``int32`` . If ``starts`` is a list or tuple, the elements of
                it should be integers or Tensors with shape [1]. If ``starts`` is an Tensor, it should be an 1-D Tensor.
6512
                It represents starting indices of corresponding axis in ``axes``.
T
Thunderbrook 已提交
6513 6514
        ends (list|tuple|Tensor): The data type is ``int32`` . If ``ends`` is a list or tuple, the elements of
                it should be integers or Tensors with shape [1]. If ``ends`` is an Tensor, it should be an 1-D Tensor .
6515
                It represents ending indices of corresponding axis in ``axes``.
G
fix  
gongweibao 已提交
6516 6517

    Returns:
T
Thunderbrook 已提交
6518
        Tensor:  A ``Tensor``. The data type is same as ``input``.
6519 6520

    Raises:
T
Thunderbrook 已提交
6521 6522
        TypeError: The type of ``starts`` must be list, tuple or Tensor.
        TypeError: The type of ``ends`` must be list, tuple or Tensor.
G
fix  
gongweibao 已提交
6523

6524 6525 6526
    Examples:
        .. code-block:: python

T
Thunderbrook 已提交
6527
            import paddle
6528

T
Thunderbrook 已提交
6529
            input = paddle.rand(shape=[4, 5, 6], dtype='float32')
6530
            # example 1:
T
Thunderbrook 已提交
6531
            # attr starts is a list which doesn't contain tensor.
6532 6533 6534
            axes = [0, 1, 2]
            starts = [-3, 0, 2]
            ends = [3, 2, 4]
T
Thunderbrook 已提交
6535
            sliced_1 = paddle.slice(input, axes=axes, starts=starts, ends=ends)
6536
            # sliced_1 is input[0:3, 0:2, 2:4].
6537 6538

            # example 2:
T
Thunderbrook 已提交
6539 6540 6541
            # attr starts is a list which contain tensor.
            minus_3 = paddle.full([1], -3, "int32")
            sliced_2 = paddle.slice(input, axes=axes, starts=[minus_3, 0, 2], ends=ends)
6542
            # sliced_2 is input[0:3, 0:2, 2:4].
G
fix  
gongweibao 已提交
6543
    """
6544
    if in_dygraph_mode():
6545 6546 6547
        attrs = ()
        starts_tensor = None
        ends_tensor = None
6548 6549

        if isinstance(axes, (list, tuple)):
6550
            axes = list(axes)
6551 6552
            if len(axes) == 0:
                raise ValueError(
6553 6554
                    "Input axes should not be an empty list/tuple."
                )
6555 6556 6557 6558 6559 6560 6561 6562
            for i in range(len(axes)):
                if axes[i] < 0:
                    axes[i] = max(0, axes[i] + len(input.shape))
                else:
                    axes[i] = min(len(input.shape) - 1, axes[i])

        else:
            raise ValueError(
6563 6564 6565 6566
                "Input axes must be a python list or tuple, but reveived {}".format(
                    type(axes)
                )
            )
6567

6568
        infer_flags = list(1 for i in range(len(axes)))
6569

J
Jiabin Yang 已提交
6570
        tmp_tensor_type = core.eager.Tensor
6571
        if isinstance(starts, (list, tuple)):
6572
            starts = [
6573
                item.numpy().item(0)
6574 6575
                if isinstance(item, tmp_tensor_type)
                else item
6576 6577
                for item in starts
            ]
6578
        elif isinstance(starts, tmp_tensor_type):
H
hong 已提交
6579 6580
            tensor_t = starts.numpy()
            starts = [ele for ele in tensor_t]
6581 6582

        if isinstance(ends, (list, tuple)):
6583
            ends = [
6584
                item.numpy().item(0)
6585 6586 6587
                if isinstance(item, tmp_tensor_type)
                else item
                for item in ends
6588
            ]
6589
            attrs += ('ends', ends)
6590
        elif isinstance(ends, tmp_tensor_type):
H
hong 已提交
6591 6592
            tensor_t = ends.numpy()
            ends = [ele for ele in tensor_t]
6593

6594
        return _C_ops.slice(input, axes, starts, ends, infer_flags, [])
J
Jiabin Yang 已提交
6595 6596 6597 6598 6599 6600 6601 6602 6603 6604
    else:
        if _in_legacy_dygraph():
            attrs = ()
            starts_tensor = None
            ends_tensor = None

            if isinstance(axes, (list, tuple)):
                axes = list(axes)
                if len(axes) == 0:
                    raise ValueError(
6605 6606
                        "Input axes should not be an empty list/tuple."
                    )
J
Jiabin Yang 已提交
6607 6608 6609 6610 6611 6612 6613 6614
                for i in range(len(axes)):
                    if axes[i] < 0:
                        axes[i] = max(0, axes[i] + len(input.shape))
                    else:
                        axes[i] = min(len(input.shape) - 1, axes[i])

            else:
                raise ValueError(
6615 6616 6617 6618
                    "Input axes must be a python list or tuple, but reveived {}".format(
                        type(axes)
                    )
                )
J
Jiabin Yang 已提交
6619 6620 6621 6622 6623 6624 6625 6626

            infer_flags = list(1 for i in range(len(axes)))

            tmp_tensor_type = Variable

            if isinstance(starts, (list, tuple)):
                starts = [
                    item.numpy().item(0)
6627 6628
                    if isinstance(item, tmp_tensor_type)
                    else item
J
Jiabin Yang 已提交
6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639
                    for item in starts
                ]
                attrs += ('starts', starts)
            elif isinstance(starts, tmp_tensor_type):
                starts_tensor = starts
                starts.stop_gradient = True
                infer_flags = list(-1 for i in range(len(axes)))

            if isinstance(ends, (list, tuple)):
                ends = [
                    item.numpy().item(0)
6640 6641
                    if isinstance(item, tmp_tensor_type)
                    else item
J
Jiabin Yang 已提交
6642 6643 6644 6645 6646 6647 6648 6649
                    for item in ends
                ]
                attrs += ('ends', ends)
            elif isinstance(ends, tmp_tensor_type):
                ends_tensor = ends
                ends_tensor.stop_gradient = True
                infer_flags = list(-1 for i in range(len(axes)))

6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661
            return _legacy_C_ops.slice(
                input,
                starts_tensor,
                ends_tensor,
                None,
                None,
                'axes',
                axes,
                'infer_flags',
                infer_flags,
                *attrs,
            )
6662

6663 6664
    if not isinstance(starts, (list, tuple, Variable)):
        raise ValueError(
6665 6666
            "Input starts must be an Variable, python list or tuple."
        )
6667 6668
    if not isinstance(ends, (list, tuple, Variable)):
        raise ValueError(
6669 6670
            "Input ends must be an Variable, python list or tuple."
        )
6671

G
fix  
gongweibao 已提交
6672
    helper = LayerHelper('slice', **locals())
6673 6674 6675 6676 6677

    inputs = {'Input': input}
    attrs = {'axes': axes}
    infer_flags = list(1 for i in range(len(axes)))

6678 6679 6680 6681 6682 6683 6684
    # starts
    if isinstance(starts, Variable):
        starts.stop_gradient = True
        inputs['StartsTensor'] = starts
        infer_flags = list(-1 for i in range(len(axes)))
    elif isinstance(starts, (list, tuple)):
        attrs['starts'] = []
L
Leo Chen 已提交
6685
        if utils._contain_var(starts):
6686
            inputs['StartsTensorList'] = utils._convert_to_tensor_list(starts)
6687 6688 6689 6690 6691 6692
            for i, dim in enumerate(starts):
                if isinstance(dim, Variable):
                    attrs['starts'].append(-1)
                    infer_flags[i] = -1
                else:
                    attrs['starts'].append(dim)
L
Leo Chen 已提交
6693 6694
        else:
            attrs['starts'] = starts
6695 6696 6697 6698 6699 6700 6701 6702

    # ends
    if isinstance(ends, Variable):
        ends.stop_gradient = True
        inputs['EndsTensor'] = ends
        infer_flags = list(-1 for i in range(len(axes)))
    elif isinstance(ends, (list, tuple)):
        attrs['ends'] = []
L
Leo Chen 已提交
6703
        if utils._contain_var(ends):
6704
            inputs['EndsTensorList'] = utils._convert_to_tensor_list(ends)
6705 6706 6707 6708 6709 6710
            for i, dim in enumerate(ends):
                if isinstance(dim, Variable):
                    attrs['ends'].append(-1)
                    infer_flags[i] = -1
                else:
                    attrs['ends'].append(dim)
L
Leo Chen 已提交
6711 6712 6713
        else:
            attrs['ends'] = ends

6714 6715
    # infer_flags
    attrs['infer_flags'] = infer_flags
X
Xin Pan 已提交
6716
    out = helper.create_variable_for_type_inference(
6717 6718 6719 6720 6721
        dtype=helper.input_dtype('input')
    )
    helper.append_op(
        type='slice', inputs=inputs, attrs=attrs, outputs={'Out': out}
    )
G
fix  
gongweibao 已提交
6722 6723 6724 6725 6726 6727

    return out


def shape(input):
    """
6728
    :alias_main: paddle.shape
6729 6730
        :alias: paddle.shape,paddle.tensor.shape,paddle.tensor.attribute.shape
        :old_api: paddle.fluid.layers.shape
6731

C
chengduozh 已提交
6732 6733
    **Shape Layer**

C
fix doc  
chengduozh 已提交
6734
    Get the shape of the input.
G
fix  
gongweibao 已提交
6735

6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752
    .. 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 已提交
6753
    Args:
6754
        input (Variable): The input can be N-D Tensor or SelectedRows with data type bool, float16, float32, float64, int32, int64.
6755
                          If input variable is type of SelectedRows, returns the shape of it's inner tensor.
G
fix  
gongweibao 已提交
6756 6757

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

6760 6761 6762
    Examples:
        .. code-block:: python

6763
            import paddle.fluid as fluid
6764
            import numpy as np
W
Wilber 已提交
6765 6766
            import paddle
            paddle.enable_static()
6767

6768
            inputs = fluid.data(name="x", shape=[3, 100, 100], dtype="float32")
6769 6770 6771 6772 6773 6774 6775 6776 6777
            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 已提交
6778
    """
6779
    if in_dygraph_mode():
6780
        out = _C_ops.shape(input)
6781 6782 6783
        out.stop_gradient = True
        return out
    if _in_legacy_dygraph():
6784
        out = _legacy_C_ops.shape(input)
W
Wilber 已提交
6785 6786 6787
        out.stop_gradient = True
        return out

6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802
    check_variable_and_dtype(
        input,
        'input',
        [
            'bool',
            'float16',
            'float32',
            'float64',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        'shape',
    )
G
fix  
gongweibao 已提交
6803
    helper = LayerHelper('shape', **locals())
6804
    out = helper.create_variable_for_type_inference(dtype='int32')
6805 6806 6807 6808 6809 6810
    helper.append_op(
        type='shape',
        inputs={'Input': input},
        outputs={'Out': out},
        stop_gradient=True,
    )
G
fix  
gongweibao 已提交
6811 6812

    return out
G
merge  
gongweibao 已提交
6813 6814


S
sneaxiy 已提交
6815 6816 6817 6818
def _elementwise_op(helper):
    op_type = helper.layer_type
    x = helper.kwargs.get('x', None)
    y = helper.kwargs.get('y', None)
X
Xin Pan 已提交
6819

S
sneaxiy 已提交
6820 6821
    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)
6822
    check_variable_and_dtype(
6823 6824 6825 6826 6827
        x,
        'x',
        ['float16', 'uint16', 'float32', 'float64', 'int32', 'int64'],
        op_type,
    )
6828
    check_variable_and_dtype(
6829 6830 6831 6832 6833
        y,
        'y',
        ['float16', 'uint16', 'float32', 'float64', 'int32', 'int64'],
        op_type,
    )
6834

S
sneaxiy 已提交
6835 6836
    axis = helper.kwargs.get('axis', -1)
    use_mkldnn = helper.kwargs.get('use_mkldnn', False)
S
sneaxiy 已提交
6837
    name = helper.kwargs.get('name', None)
6838
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
S
sneaxiy 已提交
6839

6840 6841 6842 6843 6844 6845
    helper.append_op(
        type=op_type,
        inputs={'X': x, 'Y': y},
        outputs={'Out': out},
        attrs={'axis': axis, 'use_mkldnn': use_mkldnn},
    )
S
sneaxiy 已提交
6846 6847 6848
    return helper.append_activation(out)


X
Xin Pan 已提交
6849
def elementwise_add(x, y, axis=-1, act=None, name=None):
6850
    """
6851

6852
    Examples:
6853

6854
        .. code-block:: python
6855

6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868
            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
6869

6870 6871 6872 6873
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6874

6875
            print(z_value) # [3., 8., 6.]
6876 6877


6878
        .. code-block:: python
6879

6880 6881 6882
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6883

6884 6885 6886 6887 6888 6889 6890 6891 6892 6893
            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
6894

6895 6896
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6897

6898 6899
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6900

6901
            print(z_value) # z.shape=[2,3,4,5]
6902 6903


6904
        ..  code-block:: python
6905

6906 6907 6908
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6909

6910 6911 6912 6913 6914 6915 6916 6917 6918 6919
            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
6920

6921 6922
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6923

6924 6925 6926
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
6927 6928

    """
J
Jiabin Yang 已提交
6929
    if _non_static_mode():
6930
        return _elementwise_op_in_dygraph(
6931 6932 6933 6934 6935
            x,
            y,
            axis=axis,
            act=act,
            op_name='elementwise_add',
6936 6937
            use_mkldnn=_global_flags()["FLAGS_use_mkldnn"],
        )
6938

S
sneaxiy 已提交
6939 6940 6941
    return _elementwise_op(LayerHelper('elementwise_add', **locals()))


6942
@deprecated(since="2.0.0", update_to="paddle.divide")
X
Xin Pan 已提交
6943
def elementwise_div(x, y, axis=-1, act=None, name=None):
6944
    """
6945

6946
    Examples:
6947

6948
        .. code-block:: python
6949

6950 6951 6952
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6953

6954 6955 6956 6957 6958 6959 6960 6961 6962 6963
            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
6964

6965 6966 6967 6968
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6969

6970
            print(z_value) # [2., 0.6, 2.]
6971 6972


6973
        .. code-block:: python
6974

6975 6976 6977
            import paddle.fluid as fluid
            import numpy as np
            import paddle
6978

6979 6980 6981 6982 6983 6984 6985 6986 6987 6988
            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
6989

6990 6991
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
6992

6993 6994
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
6995

6996
            print(z_value) # z.shape=[2,3,4,5]
6997 6998


6999
        ..  code-block:: python
7000

7001 7002 7003
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7004

7005 7006 7007 7008 7009 7010 7011 7012 7013 7014
            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
7015

7016 7017
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
7018

7019 7020 7021
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
7022 7023

    """
J
Jiabin Yang 已提交
7024
    if _non_static_mode():
7025 7026 7027
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_div'
        )
7028

S
sneaxiy 已提交
7029 7030 7031
    return _elementwise_op(LayerHelper('elementwise_div', **locals()))


X
Xin Pan 已提交
7032
def elementwise_sub(x, y, axis=-1, act=None, name=None):
7033
    """
7034

7035
    Examples:
7036

7037
        .. code-block:: python
7038

7039 7040 7041
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7042

7043 7044 7045 7046 7047 7048 7049 7050 7051 7052
            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
7053

7054 7055 7056 7057
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
7058

7059
            print(z_value) # [1., -2., 2.]
7060 7061


7062
        .. code-block:: python
7063

7064 7065 7066
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7067

7068 7069 7070 7071 7072 7073 7074 7075 7076 7077
            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
7078

7079 7080
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
7081

7082 7083
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
7084

7085
            print(z_value) # z.shape=[2,3,4,5]
7086 7087


7088
        ..  code-block:: python
7089

7090 7091 7092
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7093

7094 7095 7096 7097 7098 7099 7100 7101 7102 7103
            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
7104

7105 7106
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
7107

7108 7109 7110
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
7111 7112

    """
J
Jiabin Yang 已提交
7113
    if _non_static_mode():
7114 7115 7116
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_sub'
        )
7117

S
sneaxiy 已提交
7118 7119 7120
    return _elementwise_op(LayerHelper('elementwise_sub', **locals()))


7121
@deprecated(since="2.0.0", update_to="paddle.multiply")
X
Xin Pan 已提交
7122
def elementwise_mul(x, y, axis=-1, act=None, name=None):
7123
    """
7124

7125
    Examples:
7126

7127
        .. code-block:: python
7128

7129 7130 7131
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7132

7133 7134 7135 7136 7137 7138 7139 7140 7141 7142
            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
7143

7144 7145 7146 7147
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
7148

7149
            print(z_value) # [2., 15., 8.]
7150 7151


7152
        .. code-block:: python
7153

7154 7155 7156
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7157

7158 7159 7160 7161 7162 7163 7164 7165 7166 7167
            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
7168

7169 7170
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
7171

7172 7173
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
7174

7175
            print(z_value) # z.shape=[2,3,4,5]
7176 7177


7178
        ..  code-block:: python
7179

7180 7181 7182
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7183

7184 7185 7186 7187 7188 7189 7190 7191 7192 7193
            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
7194

7195 7196
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
7197

7198 7199 7200
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
7201

7202
    """
J
Jiabin Yang 已提交
7203
    if _non_static_mode():
7204 7205 7206
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_mul'
        )
7207

S
sneaxiy 已提交
7208 7209 7210 7211
    return _elementwise_op(LayerHelper('elementwise_mul', **locals()))


for func in [
7212 7213 7214 7215
    elementwise_add,
    elementwise_div,
    elementwise_sub,
    elementwise_mul,
7216 7217
]:
    op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
7218 7219

    # insert the c++ doc string on top of python doc string
7220 7221 7222 7223 7224
    func.__doc__ = (
        _generate_doc_string_(
            op_proto,
            additional_args_lines=[
                "axis (int32, optional): If X.dimension != Y.dimension, \
7225 7226
            Y.dimension must be a subsequence of x.dimension. \
            And axis is the start dimension index for broadcasting Y onto X. ",
7227
                "act (string, optional): Activation applied to the output. \
7228
            Default is None. Details: :ref:`api_guide_activations_en` ",
7229
                "name (string, optional): Name of the output. \
7230
            Default is None. It's used to print debug info for developers. Details: \
7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246
            :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__)
    )
7247

7248 7249 7250
    doc_list = func.__doc__.splitlines()

    for idx, val in enumerate(doc_list):
7251 7252 7253 7254 7255
        if (
            val.startswith("Warning: ")
            and val.endswith(" instead.")
            and "and will be removed in future versions." in val
        ):
7256 7257 7258 7259
            doc_list.insert(0, doc_list.pop(idx))
            func.__doc__ = "\n" + "\n".join(i for i in doc_list)
            break

7260
for func in []:
S
sneaxiy 已提交
7261 7262 7263 7264
    op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
    func.__doc__ = _generate_doc_string_(
        op_proto,
        additional_args_lines=[
S
sneaxiy 已提交
7265
            "act (basestring|None): Activation applied to the output.",
7266 7267 7268 7269 7270 7271
            "name (basestring|None): Name of the output.",
        ],
    )
    func.__doc__ = (
        func.__doc__
        + """
7272 7273 7274

Examples:
  .. code-block:: python
7275

7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305
    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)
7306 7307 7308 7309 7310 7311 7312 7313 7314 7315
    """
        % (
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
        )
    )
M
minqiyang 已提交
7316 7317


7318
def _logical_op(op_name, x, y, out=None, name=None, binary_op=True):
J
Jiabin Yang 已提交
7319
    if _non_static_mode():
7320
        op = getattr(_legacy_C_ops, op_name)
7321 7322 7323 7324
        if binary_op:
            return op(x, y)
        else:
            return op(x)
7325
    check_variable_and_dtype(
7326 7327
        x,
        "x",
7328
        ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
7329 7330
        op_name,
    )
7331
    if y is not None:
7332
        check_variable_and_dtype(
7333 7334
            y,
            "y",
7335
            ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
7336 7337
            op_name,
        )
7338
    if out is not None:
7339
        check_type(out, "out", Variable, op_name)
7340

M
minqiyang 已提交
7341 7342
    helper = LayerHelper(op_name, **locals())

7343 7344 7345
    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."
7346 7347
            % (op_name, x.dtype, y.dtype)
        )
M
minqiyang 已提交
7348 7349

    if out is None:
7350
        out = helper.create_variable_for_type_inference(dtype=x.dtype)
M
minqiyang 已提交
7351 7352

    if binary_op:
7353 7354 7355
        helper.append_op(
            type=op_name, inputs={"X": x, "Y": y}, outputs={"Out": out}
        )
M
minqiyang 已提交
7356 7357 7358 7359 7360 7361
    else:
        helper.append_op(type=op_name, inputs={"X": x}, outputs={"Out": out})

    return out


7362 7363 7364
@templatedoc()
def clip(x, min, max, name=None):
    """
7365
        :old_api: paddle.fluid.layers.clip
7366

7367 7368 7369 7370
    ${comment}

    Args:
        x(${x_type}): ${x_comment}
S
SunGaofeng 已提交
7371 7372
        min(float): ${min_comment}
        max(float): ${max_comment}
7373 7374
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
7375
                             For more information, please refer to :ref:`api_guide_Name`
7376 7377

    Returns:
S
SunGaofeng 已提交
7378 7379 7380 7381
        ${out_comment}

    Return Type:
        ${out_type}
7382 7383 7384 7385

    Examples:
        .. code-block:: python

S
SunGaofeng 已提交
7386
            import paddle.fluid as fluid
S
SunGaofeng 已提交
7387
            input = fluid.data(
7388 7389
                name='data', shape=[1], dtype='float32')
            reward = fluid.layers.clip(x=input, min=-1.0, max=1.0)
7390 7391 7392
    """

    helper = LayerHelper("clip", **locals())
7393
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'clip')
7394 7395

    if name is None:
7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 7409
        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},
    )
7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421

    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}
7422 7423 7424
        name(str, optional): For detailed information, please refer
            to :ref:`api_guide_Name`. Usually name is no need to set and
            None by default.
7425 7426

    Returns:
7427
        Tensor:
W
wangguanzhong 已提交
7428

7429
        out(${out_type}): ${out_comment}
7430

W
wangguanzhong 已提交
7431

7432 7433 7434
    Examples:
        .. code-block:: python

7435
            import paddle
7436
            import paddle.fluid as fluid
7437

7438 7439 7440
            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]]
7441 7442
    """

L
lyq 已提交
7443
    if in_dygraph_mode():
7444
        return _C_ops.clip_by_norm(x, max_norm)
J
Jiabin Yang 已提交
7445
    if _non_static_mode():
7446
        return _legacy_C_ops.clip_by_norm(x, 'max_norm', max_norm)
7447

7448
    helper = LayerHelper("clip_by_norm", **locals())
7449
    check_variable_and_dtype(x, 'X', ['float32', 'float16'], 'clip_by_norm')
7450
    check_type(max_norm, 'max_norm', (float), 'clip_by_norm')
7451 7452

    if name is None:
7453 7454 7455
        name = unique_name.generate_with_ignorable_key(
            ".".join([helper.name, 'tmp'])
        )
S
sneaxiy 已提交
7456

7457 7458 7459
    out = helper.create_variable(
        type=x.type, name=name, dtype=x.dtype, persistable=False
    )
7460

7461 7462 7463 7464 7465 7466
    helper.append_op(
        type="clip_by_norm",
        inputs={"X": x},
        attrs={"max_norm": max_norm},
        outputs={"Out": out},
    )
7467 7468

    return out
X
Xin Pan 已提交
7469 7470


7471
@deprecated(since="2.0.0", update_to="paddle.mean")
X
Xin Pan 已提交
7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482
@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}
7483 7484 7485 7486

    Examples:
        .. code-block:: python

7487
            import paddle
7488
            import paddle.fluid as fluid
7489 7490
            paddle.enable_static()

7491 7492
            input = fluid.layers.data(
                name='data', shape=[2, 3], dtype='float32')
7493
            mean = paddle.mean(input)
X
Xin Pan 已提交
7494
    """
7495

7496
    if _in_legacy_dygraph():
7497
        return _legacy_C_ops.mean(x)
7498
    if in_dygraph_mode():
7499
        return _C_ops.mean_all(x)
X
Xin Pan 已提交
7500 7501

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

7505 7506 7507
    helper.append_op(
        type="mean", inputs={"X": x}, attrs={}, outputs={"Out": out}
    )
X
Xin Pan 已提交
7508 7509 7510 7511

    return out


C
chengduo 已提交
7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522
@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}
7523 7524 7525 7526

    Examples:
        .. code-block:: python

7527
            import paddle.fluid as fluid
7528 7529 7530 7531 7532
            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 已提交
7533
    """
7534 7535 7536
    if in_dygraph_mode():
        return _C_ops.merge_selected_rows(x)

7537
    if _non_static_mode():
7538
        return _legacy_C_ops.merge_selected_rows(x)
C
chengduo 已提交
7539 7540 7541

    helper = LayerHelper("merge_selected_rows", **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
7542 7543 7544 7545 7546 7547
    helper.append_op(
        type="merge_selected_rows",
        inputs={"X": x},
        attrs={},
        outputs={"Out": out},
    )
C
chengduo 已提交
7548 7549 7550
    return out


X
Xin Pan 已提交
7551 7552
def mul(x, y, x_num_col_dims=1, y_num_col_dims=1, name=None):
    """
L
liu zhengxi 已提交
7553 7554 7555 7556 7557 7558 7559 7560
    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 已提交
7561 7562

    Args:
L
liu zhengxi 已提交
7563 7564
        x (Variable): The first input Tensor/LoDTensor of mul_op.
        y (Variable): The second input Tensor/LoDTensor of mul_op.
7565 7566 7567
        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 已提交
7568 7569

    Returns:
L
liu zhengxi 已提交
7570
        Variable(Tensor/LoDTensor): The output Tensor/LoDTensor of mul op.
7571 7572

    Examples:
L
liu zhengxi 已提交
7573
        ..  code-block:: python
7574

7575
            import paddle.fluid as fluid
7576 7577
            import paddle
            paddle.enable_static()
7578 7579 7580 7581 7582
            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)
7583

7584

X
Xin Pan 已提交
7585
    """
J
Jiabin Yang 已提交
7586
    if _non_static_mode():
7587 7588 7589 7590 7591 7592 7593 7594
        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 已提交
7595

7596 7597
    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 已提交
7598
    helper = LayerHelper("mul", **locals())
7599 7600
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'mul')
    check_variable_and_dtype(y, 'y', ['float16', 'float32', 'float64'], 'mul')
7601
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
X
Xin Pan 已提交
7602

7603 7604 7605
    helper.append_op(
        type="mul", inputs={"X": x, "Y": y}, attrs=attrs, outputs={"Out": out}
    )
X
Xin Pan 已提交
7606 7607 7608
    return out


7609
@deprecated(since="2.0.0", update_to="paddle.nn.functional.maxout")
X
Xin Pan 已提交
7610
@templatedoc()
7611
def maxout(x, groups, name=None, axis=1):
X
Xin Pan 已提交
7612 7613 7614 7615 7616
    """
    ${comment}

    Args:
        x(${x_type}): ${x_comment}
7617 7618
        groups(int): ${groups_comment}
        axis(int, optional): ${axis_comment}
7619 7620
        name(str, optional): For detailed information, please refer
            to :ref:`api_guide_Name`. Usually name is no need to set and
W
wangguanzhong 已提交
7621
            None by default.
X
Xin Pan 已提交
7622 7623

    Returns:
7624
        Variable: ${out_comment}
J
jerrywgz 已提交
7625

7626 7627
    Raises:
        ValueError: If `axis` is not 1, -1 or 3.
7628
        ValueError: If the number of input channels can not be divisible by `groups`.
W
wangguanzhong 已提交
7629

J
jerrywgz 已提交
7630 7631 7632
    Examples:
        .. code-block:: python

7633
            import paddle.fluid as fluid
7634 7635 7636
            import paddle
            paddle.enable_static()

7637
            input = fluid.data(
7638 7639
                name='data',
                shape=[None, 256, 32, 32],
J
jerrywgz 已提交
7640 7641
                dtype='float32')
            out = fluid.layers.maxout(input, groups=2)
X
Xin Pan 已提交
7642
    """
7643
    return paddle.nn.functional.maxout(**locals())
7644 7645


J
JiabinYang 已提交
7646
def space_to_depth(x, blocksize, name=None):
7647
    r"""
7648

J
JiabinYang 已提交
7649
    Gives a blocksize to space_to_depth the input LoDtensor with Layout: [batch, channel, height, width]
7650

7651 7652 7653
    This op rearranges blocks of spatial data, into depth. More specifically, this op outputs a copy of \
        theinput LoDtensor where values from the height and width dimensions are moved to the channel \
        dimension.
J
JiabinYang 已提交
7654
    The attr blocksize indicates the input block size.
7655

T
tianshuo78520a 已提交
7656
    space_to_depth will reorganize the elements of input with shape[batch, channel, height, width] \
7657 7658
        according to blocksize to construct output with shape \
        [batch, channel * blocksize * blocksize, height/blocksize, width/blocksize]:
J
JiabinYang 已提交
7659

J
JiabinYang 已提交
7660 7661 7662 7663 7664
    - Non-overlapping blocks of size block_size x block size are rearranged into depth at each location.
    - The Y, X coordinates within each block of the input become the high order component of the output channel index
    - channel should be divisible by square of blocksize
    - height, width should be divsible by blocksize

7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681
    This OP is useful for resizing the activations between convolutions \
        (but keeping all data)

    .. code-block:: text

        Given the input x with the shape [1, 1, 4, 4]:
        x.data = [[[[1,   2,  5,  6],
                    [3,   4,  7,  8],
                    [9,  10, 13, 14],
                    [11, 12, 15, 16]]]]
        blocksize = 2

        then get the output with the shape [1, 4, 2, 2]:
        out.data = [[[[1,   2],  [3,  4]],
                     [[5,   6],  [7,  8]],
                     [[9,  10], [11, 12]],
                     [[13, 14], [15, 16]]]]
J
JiabinYang 已提交
7682

J
JiabinYang 已提交
7683
    Args:
7684 7685 7686 7687 7688 7689
        x (Variable): The input, which should be 4 dims Tensor or LodTensor, with the shape \
            [batch, channel, height, width]
        blocksize (int): The blocksize to select the element on each feature map should be > 2
        name(str, optional): For detailed information, please refer \
            to :ref:`api_guide_Name`. Usually name is no need to set and \
            None by default.
J
JiabinYang 已提交
7690

7691
    Returns:
7692
            Tensor, The output, which should be 4 dims Tensor or LodTensor, with the shape \
7693 7694
            [batch, channel * blocksize * blocksize, height/blocksize, width/blocksize]

J
JiabinYang 已提交
7695 7696
    Examples:
        .. code-block:: python
7697

7698 7699
            import paddle.fluid as fluid
            import numpy as np
7700 7701
            import numpy as np
            import paddle
J
JiabinYang 已提交
7702

7703
            paddle.enable_static()
7704 7705
            data = fluid.data(
                name='data', shape=[1, 4, 2, 2], dtype='float32')
J
JiabinYang 已提交
7706
            space_to_depthed = fluid.layers.space_to_depth(
J
JiabinYang 已提交
7707
                x=data, blocksize=2)
7708

7709
            exe = fluid.Executor(fluid.CPUPlace())
7710
            data_np = np.arange(0,16).reshape((1,4,2,2)).astype('float32')
7711 7712 7713 7714 7715 7716 7717

            print(data_np)
            #array([[[[ 0.,  1.], [ 2.,  3.]],
            #        [[ 4.,  5.], [ 6.,  7.]],
            #        [[ 8.,  9.], [10., 11.]],
            #        [[12., 13.], [14., 15.]]]], dtype=float32)

7718
            out_main = exe.run(fluid.default_main_program(),
7719 7720 7721 7722 7723 7724 7725 7726
                        feed={'data': data_np},
                        fetch_list=[space_to_depthed])

            print(out_main)
            #[array([[[[ 0.]], [[ 4.]], [[ 1.]], [[ 5.]],
            #         [[ 8.]], [[12.]], [[ 9.]], [[13.]],
            #         [[ 2.]], [[ 6.]], [[ 3.]], [[ 7.]],
            #         [[10.]], [[14.]], [[11.]], [[15.]]]], dtype=float32)]
7727

J
JiabinYang 已提交
7728 7729
    """

J
JiabinYang 已提交
7730
    helper = LayerHelper("space_to_depth", **locals())
J
JiabinYang 已提交
7731

J
JiabinYang 已提交
7732 7733
    if not (isinstance(blocksize, int)):
        raise ValueError("blocksize must be a python Int")
J
JiabinYang 已提交
7734

7735 7736 7737 7738 7739 7740
    check_variable_and_dtype(
        x,
        'x',
        ['float16', 'float32', 'float64', 'int32', 'int64'],
        'space_to_depth',
    )
X
xujiaqi01 已提交
7741

7742
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
J
JiabinYang 已提交
7743

7744 7745 7746 7747 7748 7749
    helper.append_op(
        type="space_to_depth",
        inputs={"X": x},
        attrs={"blocksize": blocksize},
        outputs={"Out": out},
    )
J
JiabinYang 已提交
7750 7751
    return out

J
JiabinYang 已提交
7752

7753 7754 7755
def affine_channel(
    x, scale=None, bias=None, data_layout='NCHW', name=None, act=None
):
7756
    """
7757

7758 7759 7760 7761
    Applies a separate affine transformation to each channel of the input.
    Useful for replacing spatial batch norm with its equivalent fixed
    transformation. The input also can be 2D tensor and applies a affine
    transformation in second dimension.
7762

7763 7764 7765
    Args:
        x (Variable): Feature map input can be a 4D tensor with order NCHW
            or NHWC. It also can be a 2D tensor and the affine transformation
L
LielinJiang 已提交
7766
            is applied in the second dimension.The data type is float32 or float64.
7767 7768
        scale (Variable): 1D input of shape (C), the c-th element is the scale
            factor of the affine transformation for the c-th channel of
L
LielinJiang 已提交
7769
            the input.The data type is float32 or float64.
7770 7771
        bias (Variable): 1D input of shape (C), the c-th element is the bias
            of the affine transformation for the c-th channel of the input.
L
LielinJiang 已提交
7772
            The data type is float32 or float64.
7773
        data_layout (str, optional): Specify the data format of the input, and the data format of the output
7774 7775
            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:
7776
            `[batch_size, input_channels, input_height, input_width]`. If input is 2D Tensor, you can ignore
7777
            data_layout.
L
LielinJiang 已提交
7778 7779
        name (str, default None): The name of this layer. For more information,
            please refer to :ref:`api_guide_Name` .
7780
        act (str, default None): Activation to be applied to the output of this layer.
7781 7782

    Returns:
L
LielinJiang 已提交
7783
        Variable: A tensor which has the same shape, data layout and data type with x.
B
Bai Yifan 已提交
7784 7785 7786

    Examples:
        .. code-block:: python
L
LielinJiang 已提交
7787 7788

            import numpy as np
B
Bai Yifan 已提交
7789
            import paddle.fluid as fluid
7790 7791
            import paddle.fluid as fluid
            import paddle
L
LielinJiang 已提交
7792

7793
            paddle.enable_static()
L
LielinJiang 已提交
7794 7795 7796 7797 7798 7799 7800 7801 7802
            use_gpu = False
            place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()
            exe = fluid.Executor(place)

            data = fluid.data(name='data', shape=[None, 1, 2, 2], dtype='float32')
            input_scale = fluid.layers.create_parameter(shape=[1], dtype="float32",
                                    default_initializer=fluid.initializer.Constant(2.0))
            input_bias = fluid.layers.create_parameter(shape=[1],dtype="float32",
                                    default_initializer=fluid.initializer.Constant(0.5))
B
Bai Yifan 已提交
7803
            out = fluid.layers.affine_channel(data,scale=input_scale,
L
LielinJiang 已提交
7804 7805 7806 7807 7808 7809 7810 7811 7812 7813
                                    bias=input_bias)

            exe.run(fluid.default_startup_program())
            test_program = fluid.default_main_program().clone(for_test=True)

            [out_array] = exe.run(test_program,
                                  fetch_list=out,
                                  feed={'data': np.ones([1,1,2,2]).astype('float32')})
            # out_array is [[[[2.5, 2.5],
            #                [2.5, 2.5]]]] with shape: [1, 1, 2, 2]
B
Bai Yifan 已提交
7814

7815 7816
    """
    helper = LayerHelper("affine_channel", **locals())
7817 7818 7819
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'affine_channel')
    check_type(scale, 'scale', (Variable, type(None)), 'affine_channel')
    check_type(bias, 'bias', (Variable, type(None)), 'affine_channel')
7820
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
7821

7822 7823 7824 7825 7826 7827
    helper.append_op(
        type="affine_channel",
        inputs={"X": x, 'Scale': scale, 'Bias': bias},
        attrs={"data_layout": data_layout},
        outputs={"Out": out},
    )
7828
    return helper.append_activation(out)
7829 7830


B
barrierye 已提交
7831
def similarity_focus(input, axis, indexes, name=None):
7832
    r"""
B
barrierye 已提交
7833
    SimilarityFocus Operator
B
barrierye 已提交
7834 7835

    Generate a similarity focus mask with the same shape of input using the following method:
M
minqiyang 已提交
7836

7837 7838 7839
    1. Extract the 3-D tensor(here the first dimension is BatchSize) corresponding
       to the axis according to the indexes. For example, if axis=1 and indexes=[a],
       it will get the matrix T=X[:, a, :, :]. In this case, if the shape of input X
B
barrierye 已提交
7840
       is (BatchSize, A, B, C), the shape of tensor T is (BatchSize, B, C).
7841 7842 7843 7844 7845 7846 7847
    2. For each index, find the largest numbers in the tensor T, so that the same
       row and same column has at most one number(what it means is that if the
       largest number has been found in the i-th row and the j-th column, then
       the numbers in the i-th row or j-th column will be skipped. And then the
       next largest number will be selected from the remaining numbers. Obviously
       there will be min(B, C) numbers), and mark the corresponding position of the
       3-D similarity focus mask as 1, otherwise as 0. Do elementwise-or for
B
barrierye 已提交
7848
       each index.
B
barrierye 已提交
7849 7850 7851 7852
    3. Broadcast the 3-D similarity focus mask to the same shape of input X.

    Refer to `Similarity Focus Layer <http://www.aclweb.org/anthology/N16-1108>`_

B
barrierye 已提交
7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901
    .. code-block:: text

        * Example :

            Given a 4-D tensor x with the shape (BatchSize, C, A, B), where C is
            the number of channels and the shape of feature map is (A, B):
                x.shape = (2, 3, 2, 2)
                x.data = [[[[0.8, 0.1],
                            [0.4, 0.5]],

                           [[0.9, 0.7],
                            [0.9, 0.9]],

                           [[0.8, 0.9],
                            [0.1, 0.2]]],


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

                           [[0.9, 0.7],
                            [0.8, 0.4]],

                           [[0.0, 0.2],
                            [0.4, 0.7]]]]

            Given axis: 1 (the axis of the channel)
            Given indexes: [0]

            then we get a 4-D tensor out with the same shape of input x:
                out.shape = (2, 3, 2, 2)
                out.data = [[[[1.0, 0.0],
                              [0.0, 1.0]],

                             [[1.0, 0.0],
                              [0.0, 1.0]],

                             [[1.0, 0.0],
                              [0.0, 1.0]]],

                            [[[0.0, 1.0],
                              [1.0, 0.0]],

                             [[0.0, 1.0],
                              [1.0, 0.0]],

                             [[0.0, 1.0],
                              [1.0, 0.0]]]]

B
barrierye 已提交
7902
    Args:
7903
        input(Variable): The input tensor variable(default float). It should
7904
            be a 4-D tensor with shape [BatchSize, A, B, C]. Data type is
Y
Yibing Liu 已提交
7905
            float32 or float64.
B
barrierye 已提交
7906
        axis(int): Indicating the dimension to be selected. It can only be
B
barrierye 已提交
7907
            1, 2 or 3.
B
barrierye 已提交
7908
        indexes(list): Indicating the indexes of the selected dimension.
B
barrierye 已提交
7909 7910

    Returns:
H
haowang101779990 已提交
7911 7912
        Variable: A tensor variable with the same shape and same type \
                  as the input.
7913

B
barrierye 已提交
7914 7915
    Examples:
        .. code-block:: python
H
haowang101779990 已提交
7916

7917
            import paddle.fluid as fluid
7918 7919
            import paddle
            paddle.enable_static()
Y
Yibing Liu 已提交
7920
            data = fluid.data(
Y
Yibing Liu 已提交
7921 7922
                name='data', shape=[-1, 3, 2, 2], dtype='float32')
            fluid.layers.similarity_focus(input=data, axis=1, indexes=[0])
B
barrierye 已提交
7923 7924 7925
    """
    helper = LayerHelper('similarity_focus', **locals())
    # check attrs
7926 7927 7928
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], "similarity_focus"
    )
7929 7930
    check_type(axis, 'axis', int, "similarity_focus")
    check_type(indexes, 'indexes', list, "similarity_focus")
B
barrierye 已提交
7931 7932 7933 7934 7935
    if axis != 1 and axis != 2 and axis != 3:
        raise ValueError("axis must be 1, 2 or 3.")
    if len(indexes) == 0:
        raise ValueError("indexes can not be empty.")

7936
    out = helper.create_variable_for_type_inference(dtype=input.dtype)
7937 7938 7939 7940 7941 7942
    helper.append_op(
        type='similarity_focus',
        inputs={'X': input},
        outputs={'Out': out},
        attrs={"axis": axis, "indexes": indexes},
    )
B
barrierye 已提交
7943
    return out
B
barrierye 已提交
7944 7945


M
minqiyang 已提交
7946 7947
def hash(input, hash_size, num_hash=1, name=None):
    """
7948

Z
zhupengyang 已提交
7949
    This OP hash the input to an integer less than the hash_size.
M
minqiyang 已提交
7950 7951
    The hash algorithm we used was xxHash - Extremely fast hash algorithm
    (https://github.com/Cyan4973/xxHash/tree/v0.6.5)
M
minqiyang 已提交
7952 7953

    Args:
Z
zhupengyang 已提交
7954 7955 7956 7957 7958 7959
        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 已提交
7960 7961

    Returns:
Z
zhupengyang 已提交
7962
       Variable: A LoDTensor with the same data type as input.
M
minqiyang 已提交
7963 7964

    Examples:
Z
zhupengyang 已提交
7965
        .. code-block:: python
H
haowang101779990 已提交
7966

7967
            import paddle.fluid as fluid
Z
zhupengyang 已提交
7968
            import numpy as np
7969 7970
            import paddle
            paddle.enable_static()
7971

Z
zhupengyang 已提交
7972
            place = fluid.core.CPUPlace()
7973

7974 7975
            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)
7976

Z
zhupengyang 已提交
7977 7978 7979 7980
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
            in1 = np.array([[1,2],[3,4]]).astype("int32")
            print(in1)
7981
            x_i = fluid.create_lod_tensor(in1, [[0, 2]], place)
Z
zhupengyang 已提交
7982 7983 7984 7985 7986 7987 7988 7989 7990 7991
            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 已提交
7992
    """
7993
    check_variable_and_dtype(input, 'input', ['int32', 'int64'], 'hash')
7994 7995
    check_type(hash_size, 'hash_size', int, 'hash')
    check_type(num_hash, 'num_hash', int, 'hash')
M
minqiyang 已提交
7996
    helper = LayerHelper('hash', **locals())
7997 7998 7999 8000 8001 8002 8003 8004 8005
    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 已提交
8006
    return out
G
gmcather 已提交
8007 8008


D
dengkaipeng 已提交
8009
@templatedoc()
8010 8011
def grid_sampler(x, grid, name=None):
    """
8012

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

H
haowang101779990 已提交
8022
    .. code-block:: text
8023

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

K
Kaipeng Deng 已提交
8027 8028 8029 8030
        .. code-block:: text

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

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

H
haowang101779990 已提交
8036 8037 8038 8039 8040 8041 8042 8043 8044
          wn ------- y_n ------- en
          |           |           |
          |          d_n          |
          |           |           |
         x_w --d_w-- grid--d_e-- x_e
          |           |           |
          |          d_s          |
          |           |           |
          ws ------- y_s ------- wn
8045

H
haowang101779990 已提交
8046 8047 8048 8049
        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
8050

H
haowang101779990 已提交
8051 8052 8053 8054
        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
8055

H
haowang101779990 已提交
8056 8057 8058 8059
        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
8060

H
haowang101779990 已提交
8061 8062
        output = wn * d_e * d_s + en * d_w * d_s
               + ws * d_e * d_n + es * d_w * d_n
D
dengkaipeng 已提交
8063 8064

    Args:
K
Kaipeng Deng 已提交
8065 8066 8067 8068 8069 8070 8071 8072 8073
        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 已提交
8074 8075

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

H
haowang101779990 已提交
8080 8081 8082 8083
    Examples:

        .. code-block:: python

K
Kaipeng Deng 已提交
8084
            import paddle.fluid as fluid
8085 8086
            import paddle.fluid as fluid
            import paddle
K
Kaipeng Deng 已提交
8087

8088
            paddle.enable_static()
K
Kaipeng Deng 已提交
8089 8090
            # use with affine_grid
            x = fluid.data(name='x', shape=[None, 10, 32, 32], dtype='float32')
K
Kaipeng Deng 已提交
8091 8092
            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 已提交
8093
            out = fluid.layers.grid_sampler(x=x, grid=grid)
8094

D
dengkaipeng 已提交
8095 8096 8097
    """
    helper = LayerHelper("grid_sampler", **locals())

8098
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'grid_sampler')
8099 8100 8101
    check_variable_and_dtype(
        grid, 'grid', ['float32', 'float64'], 'grid_sampler'
    )
D
dengkaipeng 已提交
8102 8103 8104 8105 8106 8107
    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")

8108
    out = helper.create_variable_for_type_inference(x.dtype)
D
dengkaipeng 已提交
8109 8110
    ipts = {'X': x, 'Grid': grid}

8111 8112
    attrs = {'use_cudnn': False} if core.is_compiled_with_rocm() else {}

8113 8114 8115
    helper.append_op(
        type='grid_sampler', inputs=ipts, outputs={'Output': out}, attrs=attrs
    )
8116 8117 8118
    return out


G
gmcather 已提交
8119
def log_loss(input, label, epsilon=1e-4, name=None):
8120
    r"""
8121

G
gmcather 已提交
8122 8123 8124 8125 8126 8127 8128
    **Negative Log Loss Layer**

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

    .. math::

8129 8130
        Out = -label * \log{(input + \epsilon)}
              - (1 - label) * \log{(1 - input + \epsilon)}
G
gmcather 已提交
8131 8132

    Args:
8133
        input (Tensor|list):  A 2-D tensor with shape [N x 1], where N is the
G
gmcather 已提交
8134
                                batch size. This input is a probability computed
Y
Yibing Liu 已提交
8135
                                by the previous operator. Data type float32.
8136
        label (Tensor|list):  The ground truth which is a 2-D tensor with
8137
                                shape [N x 1], where N is the batch size.
Y
Yibing Liu 已提交
8138 8139
                                Data type float32.
        epsilon (float, optional): A small number for numerical stability. Default 1e-4.
8140
        name(str|None): For detailed information, please refer to
Y
Yibing Liu 已提交
8141
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
G
gmcather 已提交
8142 8143

    Returns:
8144
        Tensor, which shape is [N x 1], data type is float32.
G
gmcather 已提交
8145 8146 8147 8148

    Examples:
        .. code-block:: python

8149 8150 8151 8152 8153 8154
          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 已提交
8155
    """
8156
    return paddle.nn.functional.log_loss(input, label, epsilon, name)
G
gmcather 已提交
8157 8158 8159


def add_position_encoding(input, alpha, beta, name=None):
8160
    r"""
8161

G
Guo Sheng 已提交
8162 8163
    This operator performs weighted sum of input feature at each position
    (position in the sequence) and the corresponding position encoding.
G
gmcather 已提交
8164

8165
    For more details of position encoding, please refer to `Attention Is All You
G
Guo Sheng 已提交
8166
    Need <http://arxiv.org/pdf/1706.03762.pdf>`_ .
G
gmcather 已提交
8167

G
Guo Sheng 已提交
8168
    The formula is as follows:
G
gmcather 已提交
8169 8170

    .. math::
H
haowang101779990 已提交
8171 8172 8173
        PE(pos, 2i) &= \\sin{(pos / 10000^{2i / P})}   \\\\
        PE(pos, 2i + 1) &= \\cos{(pos / 10000^{2i / P})}  \\\\
        Out(:, pos, i) &= \\alpha * input(:, pos, i) + \\beta * PE(pos, i)
G
gmcather 已提交
8174 8175

    Where:
G
Guo Sheng 已提交
8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189
      - :math:`PE(pos, 2i)` : the value at even index `2i` for encoding of position `pos`.
      - :math:`PE(pos, 2i + 1)` : the value at odd index `2i+1` for encoding of position `pos`

    Args:
        input(Variable): A Tensor or LoDTensor (lod level is 1). If it is a
            Tensor, the shape should be `[N, M, P]`, where `N` stands for
            batch size, `M` for sequence length, `P` for the size of feature
            dimension. If it is a LoDTensor, the shape should be `[N, P]`,
            where `N` stands for the total sequence lengths in this mini-batch,
            `P` for the size of feature. The data type should be float32 or float64.
        alpha(float): Indicate the weight coefficient for `input` when performing
            weighted sum.
        beta(float): Indicate the weight coefficient for position encoding when
            performing weighted sum.
8190 8191
        name(str, optional): For detailed information, please refer
            to :ref:`api_guide_Name`. Usually name is no need to set and
G
Guo Sheng 已提交
8192
            None by default.
G
gmcather 已提交
8193 8194

    Returns:
G
Guo Sheng 已提交
8195
        Variable: A Tensor or LoDTensor. It has the same shape, data type and lod as `input`.
G
gmcather 已提交
8196 8197 8198 8199

    Examples:
        .. code-block:: python

8200
          import paddle
8201

8202
          tensor = paddle.randn([16, 32, 64])
8203
          position_tensor = paddle.fluid.layers.add_position_encoding(
8204
                input=tensor, alpha=1.0, beta=1.0)
H
haowang101779990 已提交
8205

G
gmcather 已提交
8206
    """
J
Jiabin Yang 已提交
8207
    if _non_static_mode():
8208 8209 8210
        return _legacy_C_ops.add_position_encoding(
            input, "alpha", alpha, "beta", beta
        )
8211

G
gmcather 已提交
8212
    helper = LayerHelper('add_position_encoding', **locals())
8213 8214 8215
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], "add_position_encoding"
    )
G
gmcather 已提交
8216 8217
    dtype = helper.input_dtype()

8218
    out = helper.create_variable_for_type_inference(dtype=dtype)
G
gmcather 已提交
8219

8220 8221 8222 8223 8224 8225
    helper.append_op(
        type="add_position_encoding",
        inputs={"X": input},
        outputs={"Out": out},
        attrs={"alpha": alpha, "beta": beta},
    )
G
gmcather 已提交
8226
    return out
Q
Qiao Longfei 已提交
8227 8228


8229 8230 8231
def bilinear_tensor_product(
    x, y, size, act=None, name=None, param_attr=None, bias_attr=None
):
8232
    r"""
8233 8234
    :api_attr: Static Graph

Y
Yibing Liu 已提交
8235
    **Bilinear Tensor Product Layer**
Q
Qiao Longfei 已提交
8236

Q
Qiao Longfei 已提交
8237
    This layer performs bilinear tensor product on two inputs.
Q
Qiao Longfei 已提交
8238 8239 8240
    For example:

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

Q
Qiao Longfei 已提交
8243
    In this formula:
8244 8245
      - :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 已提交
8246
      - :math:`W_{i}`: the i-th learned weight, shape is [M, N].
H
haowang101779990 已提交
8247
      - :math:`out_{i}`: the i-th element of out, shape is [batch_size, size].
Q
Qiao Longfei 已提交
8248 8249 8250
      - :math:`y^\mathrm{T}`: the transpose of :math:`y_{2}`.

    Args:
8251
        x (Variable): 2-D input tensor with shape [batch_size, M]. Data type
Y
Yibing Liu 已提交
8252
            is float32 or float64.
8253
        y (Variable): 2-D input tensor with shape [batch_size, N]. Data type
Y
Yibing Liu 已提交
8254
            should be same as **x**.
Q
Qiao Longfei 已提交
8255
        size (int): The dimension of this layer.
Y
Yibing Liu 已提交
8256
        act (str|None): Activation to be applied to the output of this layer. Default None.
8257
        name(str|None): For detailed information, please refer to
Y
Yibing Liu 已提交
8258
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
8259 8260
        param_attr (ParamAttr|None): To specify the weight parameter attribute.
            Default: None, which means the default weight parameter property is
Y
Yibing Liu 已提交
8261
            used. See usage for details in :ref:`api_fluid_ParamAttr` .
8262 8263
        bias_attr (ParamAttr|None): To specify the bias parameter attribute.
            Default: None, which means the default bias parameter property is
Y
Yibing Liu 已提交
8264
            used. See usage for details in :ref:`api_fluid_ParamAttr` .
Q
Qiao Longfei 已提交
8265
    Returns:
Y
Yibing Liu 已提交
8266
        Variable: A 2-D Tensor of shape [batch_size, size]. Data type is the same as input **x**.
Q
Qiao Longfei 已提交
8267 8268 8269 8270

    Examples:
        .. code-block:: python

8271 8272 8273 8274 8275
            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 已提交
8276 8277
    """
    helper = LayerHelper('bilinear_tensor_product', **locals())
Q
Qiao Longfei 已提交
8278
    dtype = helper.input_dtype('x')
Q
Qiao Longfei 已提交
8279 8280 8281

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

8282 8283 8284
    w = helper.create_parameter(
        attr=helper.param_attr, shape=param_shape, dtype=dtype, is_bias=False
    )
8285
    out = helper.create_variable_for_type_inference(dtype=dtype)
Q
Qiao Longfei 已提交
8286 8287 8288 8289

    inputs = {"X": x, "Y": y, "Weight": w}
    if helper.bias_attr:
        bias_size = [1, size]
8290 8291 8292
        bias = helper.create_parameter(
            attr=helper.bias_attr, shape=bias_size, dtype=dtype, is_bias=True
        )
Q
Qiao Longfei 已提交
8293
        inputs["Bias"] = bias
8294 8295 8296
    helper.append_op(
        type="bilinear_tensor_product", inputs=inputs, outputs={"Out": out}
    )
Q
Qiao Longfei 已提交
8297 8298 8299

    # add activation
    return helper.append_activation(out)
C
chengduo 已提交
8300 8301 8302 8303 8304


@templatedoc()
def get_tensor_from_selected_rows(x, name=None):
    """
8305 8306 8307 8308 8309 8310 8311 8312 8313
    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]]

8314
        Output is LoDTensor:
8315 8316 8317 8318 8319 8320
           out.shape = [5, 2]
           out.data = [[1, 1],
                       [2, 2],
                       [2, 2],
                       [3, 3],
                       [6, 6]]
C
chengduo 已提交
8321 8322

    Args:
8323 8324 8325
        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 已提交
8326 8327

    Returns:
8328
        Variable: LoDTensor transformed from SelectedRows. The data type is same with input.
B
bdzhuxiaoning 已提交
8329 8330 8331

    Examples:
        .. code-block:: python
8332

B
bdzhuxiaoning 已提交
8333 8334 8335 8336
            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 已提交
8337 8338
    """

8339 8340 8341 8342 8343
    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 已提交
8344 8345
    helper = LayerHelper('get_tensor_from_selected_rows', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
8346 8347 8348 8349 8350 8351
    helper.append_op(
        type='get_tensor_from_selected_rows',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={},
    )
C
chengduo 已提交
8352
    return out
8353 8354


8355
@templatedoc()
8356
def temporal_shift(x, seg_num, shift_ratio=0.25, name=None, data_format="NCHW"):
8357
    """
8358

8359
    **Temporal Shift Operator**
8360

8361
    ${comment}
8362 8363

    Args:
8364
        x(Tensor): ${x_comment}
8365
        seg_num(int): ${seg_num_comment}
D
dengkaipeng 已提交
8366
        shift_ratio(float): ${shift_ratio_comment}
K
Kaipeng Deng 已提交
8367 8368 8369
        name(str, optional): For detailed information, please refer
                             to :ref:`api_guide_Name`. Usually name is no need to set and
                             None by default.
8370 8371
        data_format(str, optional): Data format that specifies the layout of input.
            It can be "NCHW" or "NHWC". Default: "NCHW".
8372 8373

    Returns:
8374
        out(Tensor): The temporal shifting result is a tensor with the
K
Kaipeng Deng 已提交
8375
        same shape and same data type as the input.
8376 8377 8378 8379 8380 8381 8382

    Raises:
        TypeError: seg_num must be int type.

    Examples:
        .. code-block:: python

8383 8384 8385 8386
            import paddle
            import paddle.nn.functional as F

            input = paddle.randn([6, 4, 2, 2])
8387
            out = F.temporal_shift(x=input, seg_num=2, shift_ratio=0.2)
8388
    """
8389 8390 8391
    return paddle.nn.functional.temporal_shift(
        x, seg_num, shift_ratio, name, data_format
    )
8392 8393


8394
class PyFuncRegistry:
S
sneaxiy 已提交
8395 8396 8397
    _register_funcs = []

    def __init__(self, func):
S
sneaxiy 已提交
8398
        if func is None or not callable(func):
S
sneaxiy 已提交
8399 8400 8401
            raise TypeError('func must be a Python function')

        self._func = func
M
minqiyang 已提交
8402
        # find named args using reflection
8403
        args = inspect.getfullargspec(self._func)
S
sneaxiy 已提交
8404 8405 8406 8407 8408 8409
        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 已提交
8410 8411 8412
        '''
        Why record self here?

M
minqiyang 已提交
8413 8414
        1. For debug usage. Users can call
           :code:`py_func.registered_func(idx)` method
S
sneaxiy 已提交
8415
           to find the registered function corresponding
M
minqiyang 已提交
8416
           to :code:`idx`.
S
sneaxiy 已提交
8417

M
minqiyang 已提交
8418 8419
        2. For increasing reference count of self.
           It seems that to release Python object
S
sneaxiy 已提交
8420
           whose reference count is 1 would cause
M
minqiyang 已提交
8421
           segmentation fault error in C++ side.
S
sneaxiy 已提交
8422 8423
           May be lack of Python GC in C++ side?
        '''
S
sneaxiy 已提交
8424
        PyFuncRegistry._register_funcs.append(self)
S
sneaxiy 已提交
8425 8426 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438

    @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 已提交
8439 8440 8441 8442 8443 8444 8445 8446 8447
        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 已提交
8448

S
sneaxiy 已提交
8449
        if not isinstance(func_ret, (list, tuple)):
8450
            func_ret = (func_ret,)
S
sneaxiy 已提交
8451 8452

        ret = []
S
sneaxiy 已提交
8453 8454 8455
        for each_ret in func_ret:
            if each_ret is None or isinstance(each_ret, core.LoDTensor):
                ret.append(each_ret)
S
sneaxiy 已提交
8456 8457
                continue

S
sneaxiy 已提交
8458 8459
            if not isinstance(each_ret, np.ndarray):
                each_ret = np.array(each_ret)
S
sneaxiy 已提交
8460

S
sneaxiy 已提交
8461 8462 8463
            tensor = core.LoDTensor()
            tensor.set(each_ret, core.CPUPlace())
            ret.append(tensor)
S
sneaxiy 已提交
8464

S
sneaxiy 已提交
8465
        return tuple(ret)
S
sneaxiy 已提交
8466 8467


8468
@static_only
S
sneaxiy 已提交
8469 8470 8471
@templatedoc()
def py_func(func, x, out, backward_func=None, skip_vars_in_backward_input=None):
    """
8472 8473
    :api_attr: Static Graph

8474 8475
    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
8476 8477
    other easily. So you can use Python and numpy API to register a python OP.

8478 8479
    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
8480
    call ``backward_func`` at backward runtime(if ``backward_func`` is not  None).
8481 8482
    ``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.
8483

8484
    The input of the backward function ``backward_func`` is ``x``, ``out`` and
8485 8486 8487
    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``.
8488

8489 8490
    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
8491 8492 8493 8494 8495 8496 8497
    ``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
8498 8499
            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
8500
            actively convert Tensor into a numpy array, so that we can use Python and
8501
            numpy API arbitrarily. If not, some operations of numpy may not be compatible.
8502 8503 8504 8505 8506 8507 8508
        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.
8509 8510 8511
        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
8512
            ``x`` when the network is at backward runtime.
8513 8514
        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].
8515
            It must belong to either ``x`` or ``out``. The default  value is None, which means
8516 8517
            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
8518
            useful when ``backward_func`` is not None.
8519 8520

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

    Examples:
8524
        .. code-block:: python
8525

8526
            # example 1:
8527
            import paddle
8528
            import numpy as np
8529

8530 8531 8532
            paddle.enable_static()

            # Creates a forward function, Tensor can be input directly without
8533
            # being converted into numpy array.
8534 8535 8536
            def tanh(x):
                return np.tanh(x)

8537
            # Skip x in backward function and return the gradient of x
8538
            # Tensor must be actively converted to numpy array, otherwise,
8539
            # operations such as +/- can't be used.
8540 8541
            def tanh_grad(y, dy):
                return np.array(dy) * (1 - np.square(np.array(y)))
8542

8543
            # Creates a forward function for debugging running networks(print value)
8544 8545
            def debug_func(x):
                print(x)
8546

8547
            def create_tmp_var(name, dtype, shape):
8548
                return paddle.static.default_main_program().current_block().create_var(
8549
                    name=name, dtype=dtype, shape=shape)
8550 8551 8552

            def simple_net(img, label):
                hidden = img
8553
                for idx in range(4):
8554
                    hidden = paddle.static.nn.fc(hidden, size=200)
8555 8556 8557
                    new_hidden = create_tmp_var(name='hidden_{}'.format(idx),
                        dtype=hidden.dtype, shape=hidden.shape)

8558
                    # User-defined forward and backward
8559
                    hidden = paddle.static.py_func(func=tanh, x=hidden,
8560 8561 8562
                        out=new_hidden, backward_func=tanh_grad,
                        skip_vars_in_backward_input=hidden)

8563
                    # User-defined debug functions that print out the input Tensor
8564
                    paddle.static.py_func(func=debug_func, x=hidden, out=None)
8565

8566
                prediction = paddle.static.nn.fc(hidden, size=10, activation='softmax')
8567 8568 8569 8570
                ce_loss = paddle.nn.loss.CrossEntropyLoss()
                return ce_loss(prediction, label)

            x = paddle.static.data(name='x', shape=[1,4], dtype='float32')
8571
            y = paddle.static.data(name='y', shape=[1], dtype='int64')
8572 8573 8574 8575 8576
            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')
8577
            input2 = np.random.randint(1, 10, size=[1], dtype='int64')
8578 8579 8580 8581 8582 8583
            out = exe.run(paddle.static.default_main_program(),
                          feed={'x':input1, 'y':input2},
                          fetch_list=[res.name])
            print(out)

        .. code-block:: python
8584

8585
            # example 2:
8586
            # This example shows how to turn Tensor into numpy array and
8587
            # use numpy API to register an Python OP
8588
            import paddle
8589 8590
            import numpy as np

8591 8592
            paddle.enable_static()

8593
            def element_wise_add(x, y):
8594
                # Tensor must be actively converted to numpy array, otherwise,
8595
                # numpy.shape can't be used.
8596
                x = np.array(x)
8597 8598 8599 8600 8601 8602 8603 8604 8605 8606 8607 8608 8609
                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):
8610
                return paddle.static.default_main_program().current_block().create_var(
8611 8612 8613
                            name=name, dtype=dtype, shape=shape)

            def py_func_demo():
8614 8615
                start_program = paddle.static.default_startup_program()
                main_program = paddle.static.default_main_program()
8616 8617

                # Input of the forward function
8618 8619
                x = paddle.static.data(name='x', shape=[2,3], dtype='int32')
                y = paddle.static.data(name='y', shape=[2,3], dtype='int32')
8620

8621 8622 8623 8624
                # 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]
8625
                paddle.static.py_func(func=element_wise_add, x=[x,y], out=output)
8626

8627
                exe=paddle.static.Executor(paddle.CPUPlace())
8628 8629 8630 8631 8632
                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')
8633
                out = exe.run(main_program,
8634 8635 8636 8637 8638 8639 8640 8641 8642
                            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 已提交
8643
    """
S
sneaxiy 已提交
8644
    helper = LayerHelper('py_func', **locals())
8645
    check_type(x, 'X', (list, tuple, Variable, type(None)), 'py_func')
S
sneaxiy 已提交
8646 8647 8648
    if x is None:
        x = []
    elif isinstance(x, Variable):
S
sneaxiy 已提交
8649
        x = [x]
8650 8651 8652
    elif isinstance(x, tuple):
        x = list(x)
    elif not isinstance(x, (list, tuple, Variable)):
S
sneaxiy 已提交
8653
        raise TypeError('Input must be Variable/list(Variable)/tuple(Variable)')
8654
    check_type(out, 'Out', (list, tuple, Variable, type(None)), 'py_func')
S
sneaxiy 已提交
8655 8656 8657
    if out is None:
        out_list = []
    elif isinstance(out, Variable):
S
sneaxiy 已提交
8658
        out_list = [out]
8659 8660
    elif isinstance(out, tuple):
        out_list = list(out)
8661 8662 8663
    elif isinstance(out, list):
        out_list = out
    else:
S
sneaxiy 已提交
8664
        raise TypeError(
8665 8666
            'Output must be Variable/list(Variable)/tuple(Variable)'
        )
S
sneaxiy 已提交
8667

S
sneaxiy 已提交
8668
    fwd_func_id = PyFuncRegistry(func).id
8669 8670 8671
    bwd_func_id = (
        PyFuncRegistry(backward_func).id if backward_func is not None else -1
    )
S
sneaxiy 已提交
8672 8673

    for each_out in out_list:
S
sneaxiy 已提交
8674 8675
        if len(each_out.shape) == 0:
            raise ValueError(
S
sneaxiy 已提交
8676 8677
                'Output shapes of py_func op should be provided by users manually'
            )
S
sneaxiy 已提交
8678

S
sneaxiy 已提交
8679 8680 8681 8682 8683 8684 8685 8686 8687 8688 8689 8690
    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(
8691 8692 8693 8694
                    'Variable {} is not found in forward inputs and outputs'.format(
                        v.name
                    )
                )
S
sneaxiy 已提交
8695
            backward_skip_vars.add(v.name)
S
sneaxiy 已提交
8696

8697 8698 8699 8700 8701 8702 8703 8704 8705 8706
    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 已提交
8707
    return out
S
sneaxiy 已提交
8708 8709 8710


# For debug usage
S
sneaxiy 已提交
8711 8712 8713 8714
py_func.registered_func = PyFuncRegistry.registered_func
py_func.registered_func_num = PyFuncRegistry.registered_func_num


R
ruri 已提交
8715 8716 8717
def pixel_shuffle(x, upscale_factor):
    """

R
ruri 已提交
8718
    This op rearranges elements in a tensor of shape [N, C, H, W]
R
ruri 已提交
8719 8720 8721
    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.
8722
    Please refer to the paper: `Real-Time Single Image and Video Super-Resolution
R
ruri 已提交
8723 8724 8725
    Using an Efficient Sub-Pixel Convolutional Neural Network <https://arxiv.org/abs/1609.05158v2>`_ .
    by Shi et. al (2016) for more details.

R
ruri 已提交
8726
    Parameters:
R
ruri 已提交
8727

R
ruri 已提交
8728 8729
        x(Variable): 4-D tensor, the data type should be float32 or float64.
        upscale_factor(int): factor to increase spatial resolution.
R
ruri 已提交
8730 8731

    Returns:
8732
        Out(Variable): Reshaped tensor according to the new dimension.
R
ruri 已提交
8733 8734 8735 8736 8737 8738 8739

    Raises:
        ValueError: If the square of upscale_factor cannot divide the channels of input.

    Examples:
        .. code-block:: python

8740 8741 8742 8743 8744 8745 8746 8747
            # 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())
8748

8749 8750
            input_data = np.random.rand(2,9,4,4).astype("float32")
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
8751 8752 8753
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
8754

8755 8756
            # print(output.shape)
            # (2L, 1L, 12L, 12L)
R
ruri 已提交
8757 8758 8759

    """

R
ruri 已提交
8760
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'pixel_shuffle')
R
ruri 已提交
8761 8762 8763 8764 8765 8766 8767
    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")

8768 8769 8770 8771 8772 8773
    helper.append_op(
        type="pixel_shuffle",
        inputs={"X": x},
        outputs={"Out": out},
        attrs={"upscale_factor": upscale_factor},
    )
R
ruri 已提交
8774 8775 8776
    return out


8777 8778 8779 8780 8781
def fsp_matrix(x, y):
    """

    **FSP matrix op**

8782
    This op is used to calculate the flow of solution procedure (FSP) matrix of two 4-D Tensor feature maps.
8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793
    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:

8794 8795 8796
        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].
8797
                      The y_channel can be different with the x_channel of Input(X)
8798 8799
                      while the other dimensions must be the same with Input(X)'s. A Tensor with
                      type float32, float64.
8800 8801 8802 8803

    Returns:

        fsp matrix (Variable): The output of FSP op with shape [batch_size, x_channel, y_channel].
8804 8805
        The x_channel is the channel of x and the y_channel is the channel of y. A Tensor with
        type float32, float64.
8806 8807 8808 8809 8810

    Examples:

        .. code-block:: python

B
Bai Yifan 已提交
8811
            import paddle.fluid as fluid
B
Bai Yifan 已提交
8812
            data = fluid.data(name='data', shape=[None, 3, 32, 32])
B
Bai Yifan 已提交
8813 8814 8815 8816
            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)
8817 8818 8819
            loss = fluid.layers.fsp_matrix(feature_map_0, feature_map_1)

    """
8820 8821
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'fsp_matrix')
    check_variable_and_dtype(y, 'y', ['float32', 'float64'], 'fsp_matrix')
8822
    helper = LayerHelper('fsp_matrix', **locals())
8823 8824 8825
    out = helper.create_variable_for_type_inference(
        dtype=helper.input_dtype(input_param_name='x')
    )
8826 8827
    helper.append_op(type='fsp', inputs={'X': x, 'Y': y}, outputs={'Out': out})
    return out
H
heqiaozhi 已提交
8828 8829 8830


def continuous_value_model(input, cvm, use_cvm=True):
8831
    r"""
H
fix doc  
heqiaozhi 已提交
8832

H
heqiaozhi 已提交
8833
    **continuous_value_model layers**
H
fix doc  
heqiaozhi 已提交
8834

Z
zhoushiyu 已提交
8835
    Now, this OP is used in CTR project to remove or dispose show and click value in :attr:`input`.
H
fix doc  
heqiaozhi 已提交
8836

Z
zhoushiyu 已提交
8837 8838
    :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 已提交
8839
    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 已提交
8840 8841
    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 已提交
8842

Z
zhoushiyu 已提交
8843 8844 8845 8846 8847 8848 8849
    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 已提交
8850

H
heqiaozhi 已提交
8851
    Returns:
H
fix doc  
heqiaozhi 已提交
8852

Z
zhoushiyu 已提交
8853 8854
        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 已提交
8855

H
heqiaozhi 已提交
8856
    Examples:
H
fix doc  
heqiaozhi 已提交
8857

H
heqiaozhi 已提交
8858
        .. code-block:: python
H
fix doc  
heqiaozhi 已提交
8859

8860
          import paddle.fluid as fluid
Z
zhoushiyu 已提交
8861 8862
          input = fluid.data(name="input", shape=[64, 1], dtype="int64")
          label = fluid.data(name="label", shape=[64, 1], dtype="int64")
H
heqiaozhi 已提交
8863 8864 8865 8866 8867 8868 8869 8870
          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 已提交
8871

H
heqiaozhi 已提交
8872 8873 8874
    """
    helper = LayerHelper('cvm', **locals())
    out = helper.create_variable(dtype=input.dtype)
8875 8876 8877 8878 8879 8880 8881 8882 8883
    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 已提交
8884
    return out
Z
zhoukunsheng 已提交
8885 8886 8887 8888 8889 8890 8891


def where(condition):
    """
    Return an int64 tensor with rank 2, specifying the coordinate of true element in `condition`.

    Args:
8892
        condition(Variable): A bool tensor with rank at least 1, the data type is bool.
Z
zhoukunsheng 已提交
8893 8894

    Returns:
8895
        Variable, the output data type is int64. : The tensor variable storing a 2-D tensor, which involves all coordinate.
Z
zhoukunsheng 已提交
8896 8897 8898 8899

    Examples:
        .. code-block:: python

8900
             import paddle.fluid as fluid
8901 8902 8903
             import paddle.fluid.layers as layers
             import numpy as np

Z
zhoukunsheng 已提交
8904
             # condition is a tensor [True, False, True]
8905 8906 8907
             condition = layers.assign(np.array([1, 0, 1], dtype='int32'))
             condition = layers.cast(condition, 'bool')
             out = layers.where(condition) # [[0], [2]]
Z
zhoukunsheng 已提交
8908 8909

             # condition is a tensor [[True, False], [False, True]]
8910 8911 8912
             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 已提交
8913 8914

             # condition is a tensor [False, False, False]
8915 8916 8917 8918
             condition = layers.assign(np.array([0, 0, 0], dtype='int32'))
             condition = layers.cast(condition, 'bool')
             out = layers.where(condition) # [[]]

Z
zhoukunsheng 已提交
8919
    """
H
hong 已提交
8920 8921

    if in_dygraph_mode():
8922
        return _C_ops.nonzero(condition)
8923 8924
    if _in_legacy_dygraph():
        return _legacy_C_ops.where_index(condition)
8925

W
wanghuancoder 已提交
8926 8927
    helper = LayerHelper("where_index", **locals())

Z
zhoukunsheng 已提交
8928
    out = helper.create_variable_for_type_inference(
8929 8930 8931 8932 8933 8934 8935 8936
        dtype=core.VarDesc.VarType.INT64
    )

    helper.append_op(
        type='where_index',
        inputs={'Condition': condition},
        outputs={'Out': [out]},
    )
Z
zhoukunsheng 已提交
8937
    return out
Z
zhoukunsheng 已提交
8938 8939


W
WangXi 已提交
8940
@deprecated(since="2.0.0", update_to="paddle.sign")
Z
zhoukunsheng 已提交
8941
def sign(x):
8942
    r"""
8943
    This OP returns sign of every element in `x`: 1 for positive, -1 for negative and 0 for zero.
Z
zhoukunsheng 已提交
8944 8945

    Args:
8946 8947
        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 已提交
8948 8949

    Returns:
8950
        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 已提交
8951 8952 8953 8954

    Examples:
        .. code-block:: python

8955 8956 8957
          import paddle.fluid as fluid
          import numpy as np

8958
          # [1.0, 0.0, -1.0]
8959
          data = fluid.layers.sign(np.array([3.0, 0.0, -2.0], dtype='float32'))
Z
zhoukunsheng 已提交
8960 8961 8962
    """

    helper = LayerHelper("sign", **locals())
8963 8964 8965 8966
    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 已提交
8967 8968 8969 8970 8971
    out = helper.create_variable_for_type_inference(dtype=x.dtype)

    helper.append_op(type='sign', inputs={'X': [x]}, outputs={'Out': [out]})

    return out
8972 8973


Z
zhoukunsheng 已提交
8974
def unique(x, dtype='int32'):
8975
    r"""
Z
zhoukunsheng 已提交
8976 8977 8978
    Return a unique tensor for `x` and an index tensor pointing to this unique tensor.

    Args:
Z
Zhang Ting 已提交
8979 8980
        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 已提交
8981 8982 8983 8984 8985 8986 8987 8988 8989 8990

    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 已提交
8991
             x = fluid.layers.assign(np.array([2, 3, 3, 1, 5, 3], dtype='int32'))
Z
zhoukunsheng 已提交
8992 8993 8994
             out, index = fluid.layers.unique(x) # out is [2, 3, 1, 5]; index is [0, 1, 1, 2, 3, 1]
    """

8995 8996 8997
    check_variable_and_dtype(
        x, "x", ['float32', 'float64', 'int32', 'int64'], "unique"
    )
Z
zhoukunsheng 已提交
8998 8999 9000 9001 9002 9003
    helper = LayerHelper("unique", **locals())

    out = helper.create_variable_for_type_inference(dtype=x.dtype)

    index = helper.create_variable_for_type_inference(dtype)

9004 9005 9006 9007 9008 9009
    helper.append_op(
        type='unique',
        inputs={'X': x},
        attrs={'dtype': convert_np_dtype_to_dtype_(dtype)},
        outputs={'Out': [out], 'Index': [index]},
    )
Z
zhoukunsheng 已提交
9010 9011 9012 9013

    return out, index


9014
def unique_with_counts(x, dtype='int32'):
9015
    r"""
T
tianshuo78520a 已提交
9016
    This OP return a unique tensor for `x` , and count tensor that the count of unique result in raw input, \
9017
    and an index tensor pointing to this unique tensor.
9018

9019
    **NOTICE**: This op support the variable type of Tensor only.
9020 9021

    Args:
9022
        x(Variable): A 1-D input tensor with input shape of :math:`[N]` , the input data type is float32, float64, int32, int64.
9023
        dtype(np.dtype|core.VarDesc.VarType|str): The type of count and index tensor, it could be int32, int64. Default value is int32.
9024

9025
    Returns:
9026 9027 9028
        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 已提交
9029
        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\
9030
        the :attr:`x`, the data shape is :math:`[K]`, the data shape is the same as output :attr:`out`.
9031 9032 9033 9034 9035 9036 9037 9038 9039

    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]
9040
            # x.shape=(6,) out.shape=(4,), index.shape=(6,), count.shape=(4,)
9041
    """
9042 9043 9044
    check_variable_and_dtype(
        x, "x", ['float32', 'float64', 'int32', 'int64'], "unique_with_counts"
    )
9045 9046
    if not (dtype == 'int32' or dtype == 'int64'):
        raise TypeError(
9047 9048
            "Op unique_with_counts, index dtype must be int32 or int64"
        )
9049 9050 9051 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 9062

    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)

9063 9064 9065 9066 9067 9068
    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]},
    )
9069 9070 9071 9072

    return out, index, count


9073
def unfold(x, kernel_sizes, strides=1, paddings=0, dilations=1, name=None):
9074
    r"""
9075

S
SunGaofeng 已提交
9076
    This op returns a col buffer of sliding local blocks of input x, also known
9077
    as im2col for batched 2D image tensors. For each block under the convolution filter,
T
tianshuo78520a 已提交
9078
    all element will be rearranged as a column. While the convolution filter sliding over
9079 9080
    the input feature map, a series of such columns will be formed.

S
SunGaofeng 已提交
9081
    For each input :math:`x` with shape [N, C, H, W], the output shape [N, Cout, Lout]
9082 9083 9084 9085
    can be calculated as following.

    .. math::

9086
        dkernel[0] &= dilations[0] \times (kernel\_sizes[0] - 1) + 1
9087

9088
        dkernel[1] &= dilations[1] \times (kernel\_sizes[1] - 1) + 1
9089

9090
        hout &= \frac{H + paddings[0] + paddings[2] - dkernel[0]}{strides[0]} + 1
9091

9092
        wout &= \frac{W + paddings[1] + paddings[3] - dkernel[1]}{strides[1]} + 1
9093

9094
        Cout &= C \times kernel\_sizes[0] \times kernel\_sizes[1]
9095

9096
        Lout &= hout \times wout
9097 9098


S
SunGaofeng 已提交
9099
    Parameters:
9100
        x(Tensor):              4-D Tensor, input tensor of format [N, C, H, W],
S
SunGaofeng 已提交
9101
                                  data type can be float32 or float64
9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113
        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 已提交
9114
        dilations(int|list):      the dilations of convolution kernel, should be
T
tianshuo78520a 已提交
9115
                                  [dilation_h, dilation_w], or an integer dilation treated as
9116
                                  [dilation, dilation]. For default, it will be [1, 1].
9117 9118
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
9119
                             For more information, please refer to :ref:`api_guide_Name`
9120

9121

9122
    Returns:
9123
        The tensor corresponding to the sliding local blocks.
9124 9125 9126
        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 已提交
9127 9128 9129
        The data type of output is the same as the input :math:`x`

    Return Type:
9130
        Tensor
9131 9132 9133 9134 9135

    Examples:

        .. code-block:: python

9136 9137 9138 9139 9140
            import paddle
            import paddle.nn.functional as F

            x = paddle.randn((100,3,224,224))
            y = F.unfold(x, [3, 3], 1, 1, 1)
9141 9142
    """

9143 9144 9145 9146 9147 9148 9149 9150 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162
    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,
):
9163
    r"""
9164

9165
    Deformable ROI Pooling Layer
9166

9167
    Performs deformable region-of-interest pooling on inputs. As described
9168
    in `Deformable Convolutional Networks <https://arxiv.org/abs/1703.06211>`_, it will get offset for each bin after
9169
    roi pooling so that pooling at correct region. Batch_size will change to the number of region bounding boxes after deformable_roi_pooling.
9170

9171
    The operation has three steps:
9172

9173
    1. Dividing each region proposal into equal-sized sections with the pooled_width and pooled_height.
9174

9175 9176
    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.
9177

9178
    3. Sample several points in each bin to get average values as output.
9179 9180


9181 9182 9183 9184 9185 9186 9187 9188 9189
    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.
9190 9191 9192
        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.
9193 9194 9195 9196
        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.
9197
        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
9198
                          is k1 * k2 * (C + 1), which k1 and k2 are group width and height and C+1 is number of output
T
tianshuo78520a 已提交
9199
                          channels.) eg.(4, 6), which 4 is height of group and 6 is width of group. Default: [1, 1].
9200 9201 9202 9203 9204 9205 9206
        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 已提交
9207
                                   If value is True, input dimension should be output dimension * pooled_height * pooled_width. Default: False.
9208 9209 9210 9211
        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 已提交
9212 9213 9214 9215

    Examples:
      .. code-block:: python

9216 9217
        # position_sensitive=True
        import paddle.fluid as fluid
C
chengjuntao 已提交
9218
        input = fluid.data(name="input",
9219 9220
                           shape=[2, 192, 64, 64],
                           dtype='float32')
C
chengjuntao 已提交
9221 9222
        rois = fluid.data(name="rois",
                          shape=[-1, 4],
9223
                          dtype='float32',
C
chengjuntao 已提交
9224 9225
                          lod_level=1)
        trans = fluid.data(name="trans",
9226 9227 9228 9229 9230
                           shape=[2, 384, 64, 64],
                           dtype='float32')
        x = fluid.layers.deformable_roi_pooling(input=input,
                                                rois=rois,
                                                trans=trans,
C
chengjuntao 已提交
9231
                                                no_trans=False,
9232
                                                spatial_scale=1.0,
C
chengjuntao 已提交
9233 9234 9235 9236
                                                group_size=(1, 1),
                                                pooled_height=8,
                                                pooled_width=8,
                                                part_size=(8, 8),
9237
                                                sample_per_part=4,
C
chengjuntao 已提交
9238 9239
                                                trans_std=0.1,
                                                position_sensitive=True)
9240

9241
        # position_sensitive=False
9242
        import paddle.fluid as fluid
C
chengjuntao 已提交
9243
        input = fluid.data(name="input",
9244 9245
                           shape=[2, 192, 64, 64],
                           dtype='float32')
C
chengjuntao 已提交
9246 9247
        rois = fluid.data(name="rois",
                          shape=[-1, 4],
9248
                          dtype='float32',
C
chengjuntao 已提交
9249 9250
                          lod_level=1)
        trans = fluid.data(name="trans",
9251 9252 9253 9254 9255
                           shape=[2, 384, 64, 64],
                           dtype='float32')
        x = fluid.layers.deformable_roi_pooling(input=input,
                                                rois=rois,
                                                trans=trans,
C
chengjuntao 已提交
9256
                                                no_trans=False,
9257
                                                spatial_scale=1.0,
C
chengjuntao 已提交
9258 9259 9260 9261
                                                group_size=(1, 1),
                                                pooled_height=8,
                                                pooled_width=8,
                                                part_size=(8, 8),
9262
                                                sample_per_part=4,
C
chengjuntao 已提交
9263 9264
                                                trans_std=0.1,
                                                position_sensitive=False)
C
cjt222 已提交
9265 9266
    """

9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278
    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'
    )
9279
    if part_size is not None:
9280 9281 9282
        check_type(
            part_size, 'part_size', (list, tuple), 'deformable_roi_pooling'
        )
9283

C
cjt222 已提交
9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299
    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')
9300 9301 9302 9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315
    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 已提交
9316
    return output
9317 9318


9319
@deprecated(since="2.0.0", update_to="paddle.shard_index")
9320 9321
def shard_index(input, index_num, nshards, shard_id, ignore_value=-1):
    """
L
lilong12 已提交
9322 9323 9324 9325 9326 9327 9328 9329 9330
    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).
9331 9332
    ::

9333
        shard_size = (index_num + nshards - 1) // nshards
9334

L
lilong12 已提交
9335 9336 9337
    For each value `v` in `input`, we reset it to a new value according to the
    following formula:
    ::
9338

L
lilong12 已提交
9339 9340 9341 9342
        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`.
9343 9344

    Args:
L
lilong12 已提交
9345 9346
        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`.
9347 9348 9349
        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.
9350 9351

    Returns:
L
lilong12 已提交
9352
        Tensor.
9353 9354 9355 9356

    Examples:
        .. code-block:: python

9357 9358 9359 9360 9361 9362 9363 9364
            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]]
9365
    """
H
hong 已提交
9366
    if in_dygraph_mode():
9367 9368 9369
        return _C_ops.shard_index(
            input, index_num, nshards, shard_id, ignore_value
        )
H
hong 已提交
9370

B
Baibaifan 已提交
9371
    check_variable_and_dtype(input, 'input', ['int64', 'int32'], 'shard_index')
9372 9373 9374
    op_type = 'shard_index'
    helper = LayerHelper(op_type, **locals())
    if shard_id < 0 or shard_id >= nshards:
9375 9376 9377
        raise ValueError(
            'The shard_id(%d) should be in [0, %d)' % (shard_id, nshards)
        )
9378 9379

    out = helper.create_variable_for_type_inference(dtype=input.dtype)
9380 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391
    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,
    )
9392
    return out
H
huangjun12 已提交
9393 9394 9395 9396


@templatedoc()
def hard_swish(x, threshold=6.0, scale=6.0, offset=3.0, name=None):
9397
    r"""
9398 9399 9400
    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 已提交
9401

9402
    The formula is as follows:
H
huangjun12 已提交
9403

9404
    .. math::
H
huangjun12 已提交
9405

9406
        out = \\frac{x * (min(max(0, x+offset), threshold))}{scale}
H
huangjun12 已提交
9407

9408 9409 9410 9411 9412 9413 9414 9415 9416
    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
9417 9418
        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`

9419 9420
    Returns:
        Variable: The output tensor with the same shape and data type as input.
9421 9422


9423
    Examples:
9424

9425
    .. code-block:: python
9426

9427
        import paddle.fluid as fluid
9428
        import paddle
9429
        import numpy as np
9430
        paddle.enable_static()
9431

9432
        DATATYPE='float32'
9433

9434
        x_data = np.array([i for i in range(1,5)]).reshape([1,1,4]).astype(DATATYPE)
9435

9436 9437
        x = fluid.data(name="x", shape=[None,1,4], dtype=DATATYPE)
        y = fluid.layers.hard_swish(x)
9438

9439 9440 9441 9442 9443
        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 已提交
9444
    """
J
Jiabin Yang 已提交
9445
    if _non_static_mode():
9446 9447 9448
        return _legacy_C_ops.hard_swish(
            x, 'threshold', threshold, 'scale', scale, 'offset', offset
        )
9449

9450 9451 9452
    check_variable_and_dtype(
        x, 'x', ['float16', 'float32', 'float64'], 'hard_swish'
    )
9453

H
huangjun12 已提交
9454 9455
    helper = LayerHelper('hard_swish', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
9456 9457 9458 9459 9460 9461
    helper.append_op(
        type='hard_swish',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'threshold': threshold, 'scale': scale, 'offset': offset},
    )
H
huangjun12 已提交
9462
    return out
R
ruri 已提交
9463 9464


K
Kaipeng Deng 已提交
9465 9466
@templatedoc()
def mish(x, threshold=20, name=None):
9467
    r"""
K
Kaipeng Deng 已提交
9468 9469 9470 9471 9472 9473 9474 9475 9476 9477 9478 9479 9480 9481 9482 9483 9484 9485 9486 9487 9488 9489 9490 9491 9492 9493 9494 9495 9496 9497 9498 9499 9500 9501 9502 9503 9504 9505 9506 9507 9508 9509 9510 9511 9512 9513 9514 9515 9516 9517 9518 9519 9520 9521 9522 9523 9524
    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.]]
    """
9525
    if in_dygraph_mode():
9526
        return _C_ops.mish(x, threshold)
9527
    if _in_legacy_dygraph():
9528
        return _legacy_C_ops.mish(x, 'threshold', threshold)
9529

K
Kaipeng Deng 已提交
9530 9531
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'mish')
    check_type(threshold, 'threshold', (float, int), 'mish')
9532 9533 9534 9535 9536
    assert (
        threshold > 0
    ), "threshold of mish should be greater than 0, " "but got {}".format(
        threshold
    )
K
Kaipeng Deng 已提交
9537 9538 9539

    helper = LayerHelper('mish', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
9540 9541 9542 9543 9544 9545
    helper.append_op(
        type='mish',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'threshold': threshold},
    )
K
Kaipeng Deng 已提交
9546 9547 9548
    return out


G
Guo Sheng 已提交
9549
def gather_tree(ids, parents):
9550
    r"""
G
Guo Sheng 已提交
9551 9552 9553 9554 9555 9556 9557 9558 9559 9560 9561 9562 9563 9564 9565 9566 9567 9568 9569 9570 9571 9572 9573 9574
    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]]]

9575 9576
            Then:
                gather_tree(ids, parents)
G
Guo Sheng 已提交
9577 9578 9579 9580 9581 9582 9583 9584
                         = [[[2 2]
                             [1 6]]
                            [[3 3]
                             [6 1]]
                            [[0 1]
                             [9 0]]]

    Args:
L
liu zhengxi 已提交
9585
        ids(Tensor): A Tensor with shape :attr:`[length, batch_size, beam_size]`
G
Guo Sheng 已提交
9586 9587
            and data type :attr:`int32` or :attr:`int64`. It contains the selected
            ids of all time steps.
L
liu zhengxi 已提交
9588
        parents(Tensor): A Tensor with the same shape and data type as :attr:`ids`,
G
Guo Sheng 已提交
9589 9590 9591 9592
            It contains the parents corresponding to selected ids when searching
            among beams.

    Returns:
L
liu zhengxi 已提交
9593
            A Tensor with the same shape and data type as :attr:`ids`. \
G
Guo Sheng 已提交
9594 9595 9596 9597 9598 9599
            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 已提交
9600 9601 9602 9603 9604 9605 9606 9607
            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 已提交
9608 9609

    """
9610
    return paddle.nn.functional.gather_tree(ids, parents)
G
Guo Sheng 已提交
9611 9612


9613
@deprecated(since="2.0.0", update_to="paddle.uniform")
9614
@templatedoc()
9615 9616 9617
def uniform_random(
    shape, dtype='float32', min=-1.0, max=1.0, seed=0, name=None
):
9618
    """
9619 9620
    This OP returns a Tensor filled with random values sampled from a uniform
    distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.
9621 9622 9623

    Examples:
    ::
9624

9625 9626
        Input:
          shape = [1, 2]
9627

9628 9629 9630 9631
        Output:
          result=[[0.8505902, 0.8397286]]

    Args:
9632 9633 9634 9635 9636 9637 9638 9639 9640 9641 9642 9643 9644
        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
9645 9646
            use a seed generated by the system. Note that if seed is not 0,
            this operator will always generate the same random numbers every
9647
            time. Default is 0.
9648 9649 9650
        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`.
9651

9652
    Returns:
9653 9654
        Tensor: A Tensor filled with random values sampled from a uniform
        distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.
9655

9656
    Raises:
9657 9658
        TypeError: If ``shape`` is not list, tuple, Tensor.
        TypeError: If ``dtype`` is not float32, float64.
9659

9660 9661 9662
    Examples:
        .. code-block:: python

9663
            import paddle
9664
            import paddle.fluid as fluid
9665
            paddle.enable_static()
9666 9667

            # example 1:
9668
            # attr shape is a list which doesn't contain Tensor.
9669
            result_1 = fluid.layers.uniform_random(shape=[3, 4])
9670 9671 9672
            # [[ 0.84524226,  0.6921872,   0.56528175,  0.71690357],
            #  [-0.34646994, -0.45116323, -0.09902662, -0.11397249],
            #  [ 0.433519,    0.39483607, -0.8660099,   0.83664286]]
9673 9674

            # example 2:
9675 9676 9677
            # 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)
9678
            result_2 = fluid.layers.uniform_random(shape=[dim_1, dim_2])
9679 9680
            # [[-0.9951253,   0.30757582, 0.9899647 ],
            #  [ 0.5864527,   0.6607096,  -0.8886161 ]]
9681 9682

            # example 3:
9683
            # attr shape is a Tensor, the data type must be int64 or int32.
9684
            var_shape = fluid.data(name='var_shape', shape=[2], dtype="int64")
9685
            result_3 = fluid.layers.uniform_random(var_shape)
9686 9687 9688 9689
            # if var_shape's value is [2, 3]
            # result_3 is:
            # [[-0.8517412,  -0.4006908,   0.2551912 ],
            #  [ 0.3364414,   0.36278176, -0.16085452]]
9690

9691 9692 9693
    """
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
9694

9695 9696
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
9697
        return _C_ops.uniform(
9698 9699 9700 9701 9702 9703 9704
            shape,
            dtype,
            float(min),
            float(max),
            seed,
            _current_expected_place(),
        )
9705
    elif _in_legacy_dygraph():
9706
        shape = utils.convert_shape_to_list(shape)
9707 9708 9709 9710 9711 9712 9713 9714 9715 9716 9717 9718
        return _legacy_C_ops.uniform_random(
            'shape',
            shape,
            'min',
            float(min),
            'max',
            float(max),
            'seed',
            seed,
            'dtype',
            dtype,
        )
9719

9720
    check_type(shape, 'shape', (list, tuple, Variable), 'uniform_random/rand')
9721 9722 9723
    check_dtype(
        dtype, 'dtype', ('float32', 'float64', 'uint16'), 'uniform_random/rand'
    )
9724 9725
    check_type(min, 'min', (float, int, Variable), 'uniform_random/rand')
    check_type(max, 'max', (float, int, Variable), 'uniform_random/rand')
9726 9727

    inputs = dict()
9728
    attrs = {'seed': seed, 'min': min, 'max': max, 'dtype': dtype}
9729 9730 9731
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='uniform_random/rand'
    )
9732

9733
    helper = LayerHelper("uniform_random", **locals())
9734
    out = helper.create_variable_for_type_inference(dtype)
9735 9736 9737
    helper.append_op(
        type="uniform_random", inputs=inputs, attrs=attrs, outputs={"Out": out}
    )
9738
    utils.try_set_static_shape_tensor(out, shape)
9739
    return out
myq406450149's avatar
myq406450149 已提交
9740 9741 9742 9743 9744 9745 9746


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

myq406450149's avatar
myq406450149 已提交
9748 9749 9750 9751 9752 9753 9754 9755 9756 9757 9758 9759 9760 9761 9762 9763 9764 9765 9766 9767 9768 9769 9770 9771 9772
        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()
9773 9774 9775
    check_dtype(
        dtype, 'unbind', ['float32', 'float64', 'int32', 'int64'], 'unbind'
    )
myq406450149's avatar
myq406450149 已提交
9776
    if not isinstance(axis, (int)):
9777 9778 9779
        raise TypeError(
            "The type of 'axis'  must be int, but received %s." % (type(axis))
        )
myq406450149's avatar
myq406450149 已提交
9780 9781 9782 9783 9784 9785 9786 9787 9788 9789
    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)
    ]

9790 9791 9792 9793 9794 9795
    helper.append_op(
        type="unbind",
        inputs={"X": input},
        outputs={"Out": outs},
        attrs={"axis": axis},
    )
myq406450149's avatar
myq406450149 已提交
9796
    return outs