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

import numpy as np

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

Y
Yu Yang 已提交
64 65

__all__ = [
X
Xin Pan 已提交
66 67 68 69 70 71 72 73 74 75
    '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',
104
    'gather_nd',
X
Xin Pan 已提交
105 106 107
    'relu',
    'log',
    'prelu',
Z
zhoukunsheng 已提交
108
    'unique',
109
    'unique_with_counts',
X
Xin Pan 已提交
110 111 112 113 114 115 116 117 118
    'elementwise_add',
    'elementwise_div',
    'elementwise_sub',
    'elementwise_mul',
    'gaussian_random',
    'sampling_id',
    'sum',
    'slice',
    'shape',
Z
zhoukunsheng 已提交
119
    'size',
X
Xin Pan 已提交
120 121 122 123 124
    'clip',
    'clip_by_norm',
    'mean',
    'mul',
    'maxout',
J
JiabinYang 已提交
125
    'space_to_depth',
126
    'affine_channel',
B
barrierye 已提交
127
    'similarity_focus',
M
minqiyang 已提交
128
    'hash',
D
dengkaipeng 已提交
129
    'grid_sampler',
G
gmcather 已提交
130 131
    'log_loss',
    'add_position_encoding',
Q
Qiao Longfei 已提交
132
    'bilinear_tensor_product',
C
chengduo 已提交
133 134
    'merge_selected_rows',
    'get_tensor_from_selected_rows',
135
    'temporal_shift',
S
sneaxiy 已提交
136
    'py_func',
R
ruri 已提交
137
    'pixel_shuffle',
138
    'fsp_matrix',
H
heqiaozhi 已提交
139
    'continuous_value_model',
Z
zhoukunsheng 已提交
140
    'where',
Z
zhoukunsheng 已提交
141
    'sign',
142
    'unfold',
C
cjt222 已提交
143
    'deformable_roi_pooling',
144
    'shard_index',
H
huangjun12 已提交
145
    'hard_swish',
K
Kaipeng Deng 已提交
146
    'mish',
G
Guo Sheng 已提交
147
    'gather_tree',
148
    'uniform_random',
myq406450149's avatar
myq406450149 已提交
149
    'unbind',
Y
Yu Yang 已提交
150 151
]

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

Y
Yu Yang 已提交
164

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

    return reduce_all, dim


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

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

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

229
    **Fully Connected Layer**
Y
Yu Yang 已提交
230

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

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

244 245 246 247
    .. math::

        Out = Act({XW + b})

248
    When the input is a list of Tensor(or LoDTensor):
249 250 251

    .. math::

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

    In the above equation:

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

    .. code-block:: text

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

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

    Examples:
        .. code-block:: python

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

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

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

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


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

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

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

427 428 429 430
                        [[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.
431

432
        Case 2:
433

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

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

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

481 482
    Examples:
        .. code-block:: python
Y
Yu Yang 已提交
483

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

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

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

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

    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

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


548 549 550 551 552 553 554 555 556 557 558
def _pull_sparse(
    input,
    size,
    table_id,
    accessor_class,
    name="embedding",
    ctr_label_name="",
    padding_id=0,
    dtype='float32',
    scale_sparse_grad=True,
):
559
    r"""
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 603 604
    **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
605
        'is_distributed': True,
606 607
    }
    # this is only for compatible with embedding op
608 609 610 611 612 613 614 615 616
    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,
    )
617 618 619 620 621
    if len(outs) == 1:
        return outs[0]
    return outs


622 623 624 625 626 627 628 629 630 631 632
def _pull_sparse_v2(
    input,
    size,
    table_id,
    accessor_class,
    name="embedding",
    ctr_label_name="",
    padding_id=0,
    dtype='float32',
    scale_sparse_grad=True,
):
633
    r"""
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 677 678
    **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
679
        'is_distributed': True,
680 681
    }
    # this is only for compatible with embedding op
682 683 684 685 686 687 688 689 690
    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,
    )
691
    if len(outs) == 1:
Y
yaoxuefeng 已提交
692 693 694 695
        return outs[0]
    return outs


696 697 698
def _pull_gpups_sparse(
    input, size, dtype='float32', is_distributed=False, is_sparse=False
):
Y
yaoxuefeng 已提交
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 730 731
    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(
732 733 734
            "GpuPS only support float type embedding now, and your type is: "
            + dtype
        )
Y
yaoxuefeng 已提交
735 736 737 738 739 740
    helper.input_dtype()
    inputs = helper.multiple_input()
    outs = [
        helper.create_variable_for_type_inference(dtype)
        for i in range(len(inputs))
    ]
741 742 743 744 745 746 747 748 749 750 751 752 753
    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 已提交
754
    if len(outs) == 1:
755 756 757 758
        return outs[0]
    return outs


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


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

Y
yuyang18 已提交
823 824 825 826 827
    Linear Chain CRF.

    ${comment}

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

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

J
JesseyXujin 已提交
838 839 840
    Examples:
        .. code-block:: python

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

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

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

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

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

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

    return log_likelihood


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

W
wopeizl 已提交
957
    ${comment}
Y
yi.wu 已提交
958

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

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

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

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

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

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

976 977
           import paddle
           paddle.enable_static()
978 979 980

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

985 986 987 988
           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"))
989 990 991

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

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

W
wopeizl 已提交
1020
    return viterbi_path
Y
Yu Yang 已提交
1021 1022


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

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

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

    Examples:
        .. code-block:: python

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


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

1071 1072 1073 1074
    Computes dropout.

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

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

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

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

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

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

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

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

M
minqiyang 已提交
1109

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

    Examples:
1114

1115 1116
        .. code-block:: python

1117
            import paddle
1118
            import paddle.fluid as fluid
1119

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

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

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

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

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

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


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

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

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

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

1211 1212 1213 1214 1215
    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.
1216

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

1219
    .. math::
1220

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

1223
    Example:
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 1266 1267

    .. 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],
1268
                         [0.72747516, 0.72747516, 0.72747516, 0.72747516]]]
1269

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

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

    Examples:

        .. code-block:: python

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

    """
1306

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

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

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

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

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


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

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

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

C
chengduoZH 已提交
1369 1370
    .. math::

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

T
tensor-tang 已提交
1373
    Where:
C
chengduoZH 已提交
1374

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

    Example:

1384 1385
        - Input:

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

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

1390
        - Output:
T
tensor-tang 已提交
1391

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

C
chengduoZH 已提交
1394
        Where
1395 1396

        .. math::
C
chengduoZH 已提交
1397

W
weixing02 已提交
1398 1399
            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 已提交
1400 1401

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

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

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

1476 1477
          import paddle
          paddle.enable_static()
1478

1479 1480 1481
          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 已提交
1482 1483
    """

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

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

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

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

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

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

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

1552 1553 1554
    helper = LayerHelper(l_type, **locals())
    dtype = helper.input_dtype()

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

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

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

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

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

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

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

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

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

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

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

    return helper.append_activation(pre_act)


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

F
fengjiayi 已提交
1683
    ${comment}
1684 1685

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

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

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

    Examples:

        .. code-block:: python

1739
          import paddle.fluid as fluid
1740 1741 1742
          import paddle

          paddle.enable_static()
1743

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

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

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

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

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

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

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

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

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

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

    return pool_out


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

1926
    ${comment}
1927 1928

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

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

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

        .. code-block:: python

1983
          import paddle.fluid as fluid
1984 1985 1986
          import paddle

          paddle.enable_static()
1987

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

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

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

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

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

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

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

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

    pool_padding = update_padding(pool_padding, data_format)

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

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

    return pool_out


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

Q
qiaolongfei 已提交
2169 2170
    **Batch Normalization Layer**

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

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

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

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

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

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

2197

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

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

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

    Examples:

        .. code-block:: python

2269
            import paddle
2270

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

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

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

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

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

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

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

2413 2414 2415
        return dygraph_utils._append_activation_in_dygraph(
            batch_norm_out, act=act, use_mkldnn=False
        )
2416

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

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

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

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

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

    return helper.append_activation(batch_norm_out)


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

L
lvmengsi 已提交
2478 2479
    **Instance Normalization Layer**

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

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

2485
    Refer to `Instance Normalization: The Missing Ingredient for
L
lvmengsi 已提交
2486 2487 2488 2489 2490 2491 2492 2493
    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 已提交
2494
        \\ mean\ of\ one\  feature\ map\ in\ mini-batch \\\\
L
lvmengsi 已提交
2495
        \\sigma_{\\beta}^{2} &\\gets \\frac{1}{HW} \\sum_{i=1}^{HW}(x_i - \\
L
lvmengsi 已提交
2496
        \\mu_{\\beta})^2 \\qquad &//\ variance\ of\ one\ feature\ map\ in\ mini-batch \\\\
L
lvmengsi 已提交
2497 2498 2499 2500
        \\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 已提交
2501 2502
    Note:
        `H` means height of feature map, `W` means width of feature map.
L
lvmengsi 已提交
2503 2504

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

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

    Examples:

        .. code-block:: python

2532 2533
            import paddle
            paddle.enable_static()
C
ceci3 已提交
2534 2535 2536
            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 已提交
2537
    """
2538 2539 2540
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'instance_norm'
    )
C
ceci3 已提交
2541
    if param_attr is False:
2542 2543
        assert (
            bias_attr is False
2544
        ), "param_attr and bias_attr must be set to False at the same time in instance_norm"
C
ceci3 已提交
2545

L
lvmengsi 已提交
2546 2547 2548 2549 2550 2551 2552 2553
    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 已提交
2554 2555
    if len(input.shape) < 2 or len(input.shape) > 5:
        raise ValueError(
2556 2557 2558 2559
            'expected 2D or 3D or 4D or 5D input (got {}D input, input shape is: {})'.format(
                len(input.shape), input_shape
            )
        )
L
lvmengsi 已提交
2560 2561 2562 2563
    channel_num = input_shape[1]

    param_shape = [channel_num]

2564
    if param_attr != False and bias_attr != False:
C
ceci3 已提交
2565
        # create parameter
2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578
        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 已提交
2579 2580

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

    instance_norm_out = helper.create_variable_for_type_inference(dtype)

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

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

    return instance_norm_out


2611
@static_only
2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627
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,
):
2628
    r"""
2629 2630
    :api_attr: Static Graph

H
heqiaozhi 已提交
2631 2632
    **Data Normalization Layer**

2633
    This op can be used as a normalizer function for conv2d and fully_connected operations.
H
heqiaozhi 已提交
2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652
    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 已提交
2653
        input(Tensor): The input Tensor.
H
heqiaozhi 已提交
2654 2655 2656
        act(string, Default None): Activation type, linear|relu|prelu|...
        epsilon(float, Default 1e-05):
        param_attr(ParamAttr): The parameter attribute for Parameter `scale`.
2657
        data_layout (str, optional): Specify the data format of the input, and the data format of the output
2658 2659 2660
            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 已提交
2661 2662 2663 2664 2665
        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.
2666 2667
        do_model_average_for_mean_and_var(bool, Default True): Whether parameter mean and variance
            should do model average when model average is enabled.
2668
        slot_dim(int): The embedding dimension of one slot. Slot is a set of one specific feature. In pslib mode, we
2669 2670
            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).
2671 2672
            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
2673 2674
            the show number and judge if the show number is zero. If so, we choose to skip normalization on this
            embedding.
H
hutuxian 已提交
2675 2676 2677
        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.
2678
        enable_scale_and_shift(bool, Default False): do scale&shift after normalization.
H
heqiaozhi 已提交
2679 2680

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

    Examples:

        .. code-block:: python
2686

Y
yaoxuefeng 已提交
2687
            import paddle
2688
            paddle.enable_static()
H
heqiaozhi 已提交
2689

Y
yaoxuefeng 已提交
2690 2691
            x = paddle.randn(shape=[32,100])
            hidden2 = paddle.static.nn.data_norm(input=x)
H
heqiaozhi 已提交
2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709
    """
    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
2710 2711
    scale_w_default = 1.0
    bias_default = 0.0
H
heqiaozhi 已提交
2712 2713 2714 2715 2716

    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)
2717 2718 2719 2720 2721
    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
2722
    if name is None:
2723 2724
        name = "dn"
    if enable_scale_and_shift:
2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742
        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,
        )
2743
    # create parameter
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 2771 2772
    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 已提交
2773 2774 2775 2776 2777 2778

    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)

2779 2780 2781 2782
    inputs = {
        "X": input,
        "BatchSize": batch_size,
        "BatchSum": batch_sum,
2783
        "BatchSquareSum": batch_square_sum,
2784
    }
2785 2786
    attrs = {
        "epsilon": epsilon,
X
XiangGao 已提交
2787
        "data_layout": data_layout,
2788 2789 2790 2791 2792 2793 2794
        "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
2795 2796 2797
    if enable_scale_and_shift:
        inputs["scale_w"] = scale_w
        inputs["bias"] = bias
2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810
    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 已提交
2811 2812 2813 2814

    return helper.append_activation(data_norm_out)


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

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

    The formula is as follows:

Y
yuyang18 已提交
2837
    ..  math::
G
guosheng 已提交
2838

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

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

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

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

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

    Returns:
2877
        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 已提交
2878 2879 2880

    Examples:

2881 2882
        .. code-block:: python

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

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

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

    return helper.append_activation(layer_norm_out)


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

D
Dun 已提交
2965 2966
    **Group Normalization Layer**

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

2969
    Parameters:
2970
        input(Tensor): Tensor with dimension greater than 1, the data type is float32 or float64.
2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982
        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 已提交
2983
        act(str, optional): Activation to be applied to the output of group normalization.
2984
        data_layout(str, optional): Specify the data format of the input, and the data format of the output
2985 2986
            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:
2987
            `[batch_size, input_channels, *]`.
2988 2989
        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 已提交
2990 2991

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

    Examples:
2995
       .. code-block:: python
D
Dun 已提交
2996

2997 2998
            import paddle
            paddle.enable_static()
2999

C
Chen Long 已提交
3000 3001 3002
            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 已提交
3003 3004 3005
    """
    helper = LayerHelper('group_norm', **locals())
    dtype = helper.input_dtype()
3006 3007 3008
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], 'group_norm'
    )
D
Dun 已提交
3009 3010 3011
    # create intput and parameters
    inputs = {'X': input}
    input_shape = input.shape
3012 3013 3014 3015
    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)}"
        )
3016 3017 3018
    if data_layout != 'NCHW' and data_layout != 'NHWC':
        raise ValueError(
            "Param(data_layout) of Op(fluid.layers.group_norm) got wrong value: received "
3019 3020 3021
            + data_layout
            + " but only NCHW or NHWC supported."
        )
3022 3023
    channel_num = input_shape[1] if data_layout == 'NCHW' else input_shape[-1]
    param_shape = [channel_num]
D
Dun 已提交
3024
    if param_attr:
3025 3026 3027 3028 3029 3030
        scale = helper.create_parameter(
            attr=helper.param_attr,
            shape=param_shape,
            dtype=dtype,
            default_initializer=Constant(1.0),
        )
D
Dun 已提交
3031 3032
        inputs['Scale'] = scale
    if bias_attr:
3033 3034 3035
        bias = helper.create_parameter(
            attr=helper.bias_attr, shape=param_shape, dtype=dtype, is_bias=True
        )
D
Dun 已提交
3036 3037 3038
        inputs['Bias'] = bias

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

3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056
    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 已提交
3057 3058 3059 3060 3061

    return helper.append_activation(group_norm_out)


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

D
dengkaipeng 已提交
3066 3067
    **Spectral Normalization Layer**

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

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

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

3083
    .. math::
D
dengkaipeng 已提交
3084 3085 3086 3087 3088 3089

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

    .. math::

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

D
dengkaipeng 已提交
3096
        \mathbf{W} = \\frac{\mathbf{W}}{\sigma(\mathbf{W})}
3097

3098

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

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

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

    Examples:
K
Kaipeng Deng 已提交
3115
       .. code-block:: python
D
dengkaipeng 已提交
3116

3117
            import paddle
K
Kaipeng Deng 已提交
3118

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

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

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

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

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

3182
    return out
D
Dun 已提交
3183 3184


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

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

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

    Returns:
3206 3207
        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 已提交
3208

3209 3210
    Raises:
        TypeError, if out data type is different with the input data type.
3211

G
guosheng 已提交
3212 3213 3214
    Examples:
        .. code-block:: python

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

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

G
guosheng 已提交
3236
    """
3237 3238
    reduce_all, dim = _get_reduce_dim(dim, input)

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


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

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

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

3288 3289
    Raises:
        TypeError, if out data type is different with the input data type.
3290

G
guosheng 已提交
3291 3292 3293
    Examples:
        .. code-block:: python

3294
            import paddle
3295
            import paddle.fluid as fluid
3296 3297
            paddle.enable_static()

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

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

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


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

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

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

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

    Examples:
        .. code-block:: python
3343

3344
            import paddle
3345
            import paddle.fluid as fluid
3346 3347 3348
            import paddle.fluid.layers as layers
            import numpy as np

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

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

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

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

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

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


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

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

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

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

3410
            import paddle
3411
            import paddle.fluid as fluid
3412 3413 3414
            import paddle.fluid.layers as layers
            import numpy as np

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

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

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

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


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

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

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

3471
    Example:
G
guosheng 已提交
3472 3473
        .. code-block:: python

3474 3475
            import paddle.fluid as fluid

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

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

3495 3496 3497 3498 3499 3500
            # 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]
3501

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

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

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

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

G
guosheng 已提交
3554
    helper = LayerHelper('split', **locals())
3555

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

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

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

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


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

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

3634
    .. math::
3635 3636

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

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

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

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

    Examples:
3654

3655 3656
    .. code-block:: python
        :name: code-example1
3657

3658
        import paddle
3659

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

3664 3665 3666
        # [[ 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]]
3667

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

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

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


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

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

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

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

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

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

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

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

G
guosheng 已提交
3739 3740 3741
    Examples:
        .. code-block:: python

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

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

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

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

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

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

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

3764
            import paddle
3765
            import paddle.fluid as fluid
3766 3767
            paddle.enable_static()

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

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

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

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

S
ShenLiang 已提交
3832 3833 3834 3835
    __check_input(x, y)

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


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

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

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

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

F
fengjiayi 已提交
3860 3861
    .. code-block:: text

3862 3863 3864 3865 3866
        Case 1:

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

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

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

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

    Returns:
3891 3892
        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 已提交
3893

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

    Examples:
        .. code-block:: python

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

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

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

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


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

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

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

3960 3961 3962 3963 3964
    A simple example as below:

    .. code-block:: text

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

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

3977
        input.lod = [[4, 4]]
M
minqiyang 已提交
3978

W
whs 已提交
3979
        Computation:
3980

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

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

3992
        output.lod = [[2, 1]]
3993

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

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

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

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

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

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

4057 4058 4059 4060

    Examples:
        .. code-block:: python

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

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

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

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

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

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

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


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

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

    .. math::

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

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

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

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

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

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

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

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

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

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

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

4212
            output.dims = {8, 8}
4213

4214
            output.lod = [[4, 4]]
4215

T
Tink_Y 已提交
4216
    Examples:
4217 4218 4219

        .. code-block:: python

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

4228 4229

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

4234 4235
    check_variable_and_dtype(input, 'input', ['float32'], 'im2sequence')

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


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

Y
yuyang18 已提交
4265
    ${comment}
4266 4267

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

    Returns:
Y
yuyang18 已提交
4276
        ${out_comment}.
4277 4278

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

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


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

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

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

4316
    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 已提交
4317

4318
    For Example:
L
lujun 已提交
4319

4320
            .. code-block:: text
L
lujun 已提交
4321

4322
                Given:
L
lujun 已提交
4323

4324 4325 4326 4327
                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 已提交
4328

4329
                index = [[3],[0],[1],[2]]
L
lujun 已提交
4330

4331 4332 4333 4334
                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 已提交
4335 4336


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

    Examples:
4347

X
xuezhong 已提交
4348 4349
        .. code-block:: python

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

4359
    """
4360 4361

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

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

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


4390 4391
def smooth_l1(x, y, inside_weight=None, outside_weight=None, sigma=None):
    """
4392

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

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

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

    Examples:
        .. code-block:: python

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

4441 4442 4443 4444
            #[array([[0.08220536],
            #       [0.36652038],
            #      [0.20541131]], dtype=float32)]

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

4449
    helper = LayerHelper('smooth_l1_loss', **locals())
4450

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


4467
@deprecated(since='2.0.0', update_to='paddle.nn.functional.one_hot')
4468
def one_hot(input, depth, allow_out_of_range=False):
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 4506 4507

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

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

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

    Examples:
C
caoying03 已提交
4541
        .. code-block:: python
4542

4543
            import paddle
4544
            import paddle.fluid as fluid
4545 4546
            paddle.enable_static()

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

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

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


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

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

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

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

    Examples:
        .. code-block:: python

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

    return counter
Y
yangyaming 已提交
4632 4633


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

M
minqiyang 已提交
4640
    For example:
H
haowang101779990 已提交
4641 4642 4643

    .. code-block:: text

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

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

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

    Examples:
        .. code-block:: python

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

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

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

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

4720 4721
    return out

4722

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

    .. code-block:: text

        * Example 1:

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

4741
            target_lod: [4, 2]
Y
yangyaming 已提交
4742 4743

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

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

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

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

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

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

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

    Examples:
        .. code-block:: python

4799
            import paddle.fluid as fluid
4800 4801 4802
            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 已提交
4803
    """
4804 4805 4806
    check_variable_and_dtype(
        x, 'x', ['float32', 'float64', 'int32', 'int64'], 'lod_reset'
    )
Y
yangyaming 已提交
4807
    helper = LayerHelper("lod_reset", **locals())
X
Xin Pan 已提交
4808
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
Y
yangyaming 已提交
4809
    if y is not None:
4810
        check_type(y, 'y', (Variable), 'lod_reset')
4811 4812 4813 4814
        # TODO: check y.lod_level = 0 dtype
        helper.append_op(
            type="lod_reset", inputs={'X': x, 'Y': y}, outputs={'Out': out}
        )
Y
yangyaming 已提交
4815
    elif target_lod is not None:
4816 4817 4818 4819 4820 4821
        helper.append_op(
            type="lod_reset",
            inputs={'X': x},
            attrs={'target_lod': target_lod},
            outputs={'Out': out},
        )
Y
yangyaming 已提交
4822
    else:
4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847
        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:
4848
        x (Variable): Input variable which could be a tensor or LoDTensor.
4849
                      The data type should be int32, int64, float32 or float64.
4850
        level (list|tuple|Variable, optional): The LoD level to be appended into LoD of x.
4851 4852
                                               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.
4853 4854 4855 4856 4857
    Returns:
        Variable: Output variable with new LoD level.

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

4859 4860 4861 4862 4863 4864 4865 4866 4867
    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.")
4868 4869 4870
    if (not isinstance(level, Iterable)) and (not isinstance(level, Variable)):
        raise ValueError("Input(level) must be list, tuple or Variable.")

4871 4872 4873
    check_variable_and_dtype(
        x, 'x', ['float32', 'float64', 'int32', 'int64'], 'lod_append'
    )
4874

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

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

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


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

S
SunGaofeng 已提交
4898 4899
    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 已提交
4900

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

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

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

    Return Type:
        Variable
G
guosheng 已提交
4938 4939 4940

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

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

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

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


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

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

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

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

5002
    Supporting resample methods:
5003
        'LINEAR' : Linear interpolation
Q
update  
qiaolongfei 已提交
5004

5005
        'BILINEAR' : Bilinear interpolation
T
Tink_Y 已提交
5006

K
Kaipeng Deng 已提交
5007 5008
        'TRILINEAR' : Trilinear interpolation

5009
        'NEAREST' : Nearest neighbor interpolation
5010

5011
        'BICUBIC' : Bicubic interpolation
5012 5013

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

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

    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
5024 5025
    again in the other direction.

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

5031 5032 5033 5034
    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 已提交
5035

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

    Example:

T
Tink_Y 已提交
5041
    .. code-block:: text
5042

T
Tink_Y 已提交
5043
        For scale:
5044

T
Tink_Y 已提交
5045
            if align_corners = True && out_size > 1 :
5046

T
Tink_Y 已提交
5047
              scale_factor = (in_size-1.0)/(out_size-1.0)
5048

T
Tink_Y 已提交
5049
            else:
5050

T
Tink_Y 已提交
5051
              scale_factor = float(in_size/out_size)
5052 5053


T
Tink_Y 已提交
5054
        Nearest neighbor interpolation:
5055

T
Tink_Y 已提交
5056 5057
          if:
              align_corners = False
5058

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

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

T
Tink_Y 已提交
5065 5066
          else:
              align_corners = True
5067

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

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

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

          if:
              align_corners = False , align_mode = 0
5095

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

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

T
Tink_Y 已提交
5102
          else:
5103

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

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

K
Kaipeng Deng 已提交
5110 5111 5112 5113
        Trilinear interpolation:

          if:
              align_corners = False , align_mode = 0
5114

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

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

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

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

5145

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

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

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

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

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

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

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

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

5225 5226
    Examples:
        .. code-block:: python
5227

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

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

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

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

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

5256 5257 5258
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5259

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

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

5267
            print(output_data[0].shape)
5268

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

5278 5279
            #imperative mode
            import paddle.fluid.dygraph as dg
5280

5281 5282 5283 5284
            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)
5285

5286
                # [2L, 3L, 12L, 12L]
5287

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

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

5311 5312 5313 5314 5315
    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")

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

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

5340
    def _is_list_or_turple_(data):
5341
        return isinstance(data, list) or isinstance(data, tuple)
5342

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

    Example:

T
Tink_Y 已提交
5531
    .. code-block:: text
5532

T
Tink_Y 已提交
5533
        For scale:
5534

T
Tink_Y 已提交
5535
            if align_corners = True && out_size > 1 :
5536

T
Tink_Y 已提交
5537
              scale_factor = (in_size-1.0)/(out_size-1.0)
5538

T
Tink_Y 已提交
5539
            else:
5540

5541
              scale_factor = float(in_size/out_size)
5542

T
Tink_Y 已提交
5543 5544 5545 5546
        Bilinear interpolation:

          if:
              align_corners = False , align_mode = 0
5547

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

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

T
Tink_Y 已提交
5554
          else:
T
tink2123 已提交
5555

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

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

    Returns:
5594
        Variable: 4-D tensor(NCHW or NHWC).
5595

5596 5597
    Examples:
        .. code-block:: python
5598

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

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

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

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

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

5627 5628 5629
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5630

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

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

5638
            print(output_data[0].shape)
5639

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

5649 5650
            #imperative mode
            import paddle.fluid.dygraph as dg
5651

5652 5653 5654 5655
            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)
5656

5657
                # [2L, 3L, 12L, 12L]
5658

5659 5660
    """

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


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

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

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

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

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

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

    Example:

    .. code-block:: text

        For scale:
5710

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

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

K
Kaipeng Deng 已提交
5715
            else:
5716 5717

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

        Bilinear interpolation:

          if:
5722

K
Kaipeng Deng 已提交
5723
              align_corners = False , align_mode = 0
5724

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

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

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

    Examples:
        .. code-block:: python
5775

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

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

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

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

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

5804 5805 5806
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5807

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

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

5815
            print(output_data[0].shape)
R
ruri 已提交
5816

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

5826 5827
            #imperative mode
            import paddle.fluid.dygraph as dg
5828

5829 5830 5831 5832
            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)
5833

5834
                # [2L, 3L, 12L, 12L, 12L]
5835 5836 5837



K
Kaipeng Deng 已提交
5838 5839
    """

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


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

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

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

5872 5873
    Example:

T
Tink_Y 已提交
5874 5875 5876
    .. code-block:: text

        For scale:
5877

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

T
Tink_Y 已提交
5881
            else:
5882

T
Tink_Y 已提交
5883
              scale_factor = float(in_size/out_size)
5884

T
Tink_Y 已提交
5885
        Nearest neighbor interpolation:
5886

T
Tink_Y 已提交
5887 5888
          if:
              align_corners = False
5889

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

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

T
Tink_Y 已提交
5896 5897
          else:
              align_corners = True
5898

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

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


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

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

    Returns:
5938
        Variable: 4-D tensor(NCHW or NHWC).
5939 5940 5941

    Examples:
        .. code-block:: python
5942

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

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

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

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

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

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

5972 5973 5974
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
5975

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

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

5983
            print(output_data[0].shape)
R
ruri 已提交
5984

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

5994 5995
            #imperative mode
            import paddle.fluid.dygraph as dg
5996

5997 5998 5999 6000
            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 已提交
6001

6002
                # [2L, 3L, 12L, 12L]
6003 6004 6005



6006 6007
    """

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


6021
@deprecated(since="2.0.0", update_to="paddle.gather_nd")
6022 6023 6024 6025
def gather_nd(input, index, name=None):
    """
    **Gather Nd Layer**

6026 6027 6028 6029
    This function is actually a high-dimensional extension of :code:`gather`
    and supports for simultaneous indexing by multiple axes. :attr:`index` is a
    K-dimensional integer tensor, which is regarded as a (K-1)-dimensional
    tensor of :attr:`index` into :attr:`input`, where each element defines
6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051
    a slice of params:

    .. math::

        output[(i_0, ..., i_{K-2})] = input[index[(i_0, ..., i_{K-2})]]

    Obviously, :code:`index.shape[-1] <= input.rank` . And, the output tensor has
    shape :code:`index.shape[:-1] + input.shape[index.shape[-1]:]` .

    .. code-block:: text

            Given:
                input = [[[ 0,  1,  2,  3],
                          [ 4,  5,  6,  7],
                          [ 8,  9, 10, 11]],
                         [[12, 13, 14, 15],
                          [16, 17, 18, 19],
                          [20, 21, 22, 23]]]
                input.shape = (2, 3, 4)

            * Case 1:
                index = [[1]]
6052 6053 6054

                gather_nd(input, index)
                         = [input[1, :, :]]
6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073
                         = [[12, 13, 14, 15],
                            [16, 17, 18, 19],
                            [20, 21, 22, 23]]

            * Case 2:
                index = [[0,2]]

                gather_nd(input, index)
                         = [input[0, 2, :]]
                         = [8, 9, 10, 11]

            * Case 3:
                index = [[1, 2, 3]]

                gather_nd(input, index)
                         = [input[1, 2, 3]]
                         = [23]

    Args:
6074
        input (Tensor): The input Tensor which it's data type should be bool, float32, float64, int32, int64.
6075 6076 6077 6078
        index (Tensor): The index input with rank > 1, index.shape[-1] <= input.rank.
                        Its dtype should be int32, 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` .
6079 6080

    Returns:
6081
        output (Tensor): A tensor with the shape index.shape[:-1] + input.shape[index.shape[-1]:]
6082 6083 6084 6085 6086

    Examples:

        .. code-block:: python

6087
            import paddle
6088
            import paddle.fluid as fluid
6089 6090
            paddle.enable_static()

6091 6092
            x = fluid.data(name='x', shape=[3, 4, 5], dtype='float32')
            index = fluid.data(name='index', shape=[2, 2], dtype='int32')
6093 6094 6095
            output = fluid.layers.gather_nd(x, index)

    """
6096
    if in_dygraph_mode():
6097
        return _C_ops.gather_nd(input, index)
J
Jiabin Yang 已提交
6098 6099
    else:
        if _in_legacy_dygraph():
6100
            return _legacy_C_ops.gather_nd(input, index)
6101
    check_variable_and_dtype(
6102 6103 6104 6105 6106
        input,
        'input',
        ['bool', 'float32', 'float64', 'int16', 'int32', 'int64'],
        'gather_np',
    )
6107
    check_variable_and_dtype(index, 'index', ['int32', 'int64'], 'gather_np')
6108 6109
    helper = LayerHelper('gather_nd', **locals())
    dtype = helper.input_dtype()
6110
    output = helper.create_variable_for_type_inference(dtype)
6111 6112 6113 6114 6115
    helper.append_op(
        type="gather_nd",
        inputs={"X": input, "Index": index},
        outputs={"Out": output},
    )
6116 6117 6118
    return output


6119
def log(x, name=None):
6120
    r"""
W
wanghaoshuang 已提交
6121 6122 6123 6124
    Calculates the natural log of the given input tensor, element-wise.

    .. math::

6125
        Out = \\ln(x)
W
wanghaoshuang 已提交
6126 6127

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

W
wanghaoshuang 已提交
6131 6132

    Returns:
S
Steffy-zxf 已提交
6133
        Tensor: The natural log of the input Tensor computed element-wise.
W
wanghaoshuang 已提交
6134 6135 6136 6137 6138

    Examples:

        .. code-block:: python

S
Steffy-zxf 已提交
6139
            import paddle
W
Wilber 已提交
6140

S
Steffy-zxf 已提交
6141 6142 6143 6144
            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 已提交
6145
    """
6146
    if in_dygraph_mode():
W
wanghuancoder 已提交
6147
        return _C_ops.log(x)
6148 6149
    if _in_legacy_dygraph():
        return _legacy_C_ops.log(x)
6150

6151
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], "log")
6152
    inputs = {'X': [x]}
W
wanghaoshuang 已提交
6153
    helper = LayerHelper('log', **locals())
W
wanghaoshuang 已提交
6154
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
6155
    out = helper.create_variable_for_type_inference(dtype)
W
wanghaoshuang 已提交
6156
    helper.append_op(type="log", inputs={"X": x}, outputs={"Out": out})
W
wanghaoshuang 已提交
6157 6158 6159
    return out


6160
@deprecated(since="2.0.0", update_to="paddle.nn.functional.relu")
6161
def relu(x, name=None):
W
wanghaoshuang 已提交
6162
    """
Z
zhupengyang 已提交
6163
    ${comment}
W
wanghaoshuang 已提交
6164 6165

    Args:
Z
zhupengyang 已提交
6166 6167 6168 6169
        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 已提交
6170 6171

    Returns:
Z
zhupengyang 已提交
6172
        Variable: ${out_comment}
W
wanghaoshuang 已提交
6173 6174 6175 6176 6177

    Examples:

        .. code-block:: python

6178
            import paddle.fluid as fluid
Z
zhupengyang 已提交
6179 6180 6181 6182 6183 6184 6185
            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. ]
6186
                #  [1.  2.6]]"""
6187 6188

    if in_dygraph_mode():
W
wanghuancoder 已提交
6189
        return _C_ops.relu(x)
6190 6191
    if _in_legacy_dygraph():
        return _legacy_C_ops.relu(x)
6192

6193 6194
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'relu')

6195
    inputs = {'X': [x]}
W
wanghaoshuang 已提交
6196
    helper = LayerHelper('relu', **locals())
W
wanghaoshuang 已提交
6197
    dtype = helper.input_dtype(input_param_name='x')
X
Xin Pan 已提交
6198
    out = helper.create_variable_for_type_inference(dtype)
6199 6200 6201
    helper.append_op(
        type="relu", inputs={"X": helper.input('x')}, outputs={"Out": out}
    )
W
wanghaoshuang 已提交
6202
    return out
6203 6204


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

Z
zhupengyang 已提交
6209
    prelu activation.
J
jerrywgz 已提交
6210

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

J
jerrywgz 已提交
6214 6215 6216 6217 6218 6219 6220 6221
    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 已提交
6222 6223
    Parameters:
        x (Tensor): The input Tensor or LoDTensor with data type float32.
6224
        mode (str): The mode for weight sharing.
U
ustiniankw 已提交
6225 6226 6227
        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`.
6228 6229
        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 已提交
6230 6231
        name (str, optional): Name for the operation (optional, default is None).
            For more information, please refer to :ref:`api_guide_Name`.
J
jerrywgz 已提交
6232 6233

    Returns:
U
ustiniankw 已提交
6234
        Tensor, A tensor with the same shape and data type as x.
J
jerrywgz 已提交
6235 6236 6237 6238

    Examples:
        .. code-block:: python

6239
            import paddle
Z
zhupengyang 已提交
6240 6241 6242 6243 6244

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

J
jerrywgz 已提交
6246
    """
G
Guoxia Wang 已提交
6247
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'prelu')
6248

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

J
jerrywgz 已提交
6253 6254
    alpha_shape = [1]
    if mode == 'channel':
6255 6256

        true_data_format = [
6257 6258 6259 6260 6261 6262 6263
            'NC',
            'NCL',
            'NCHW',
            'NCDHW',
            'NLC',
            'NHWC',
            'NDHWC',
6264 6265 6266 6267
        ]
        if data_format not in true_data_format:
            raise ValueError(
                "data_format must be one of 'NC', 'NCL', 'NCHW', 'NCDHW', "
6268 6269
                "'NLC', 'NHWC', 'NDHWC' but receive {}".format(data_format)
            )
6270 6271 6272

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

6273 6274 6275 6276
        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:]).
6277
        # To be consistent with Prelu, it is simplified.
6278 6279
        # NOTE(zhiqiu): Revert shape to [1, channel, 1, 1] for compatibility with saved model of old version.
        # NOTE(GuoxiaWang): support NHWC data format
6280
        if data_format == 'NHWC':
6281
            alpha_shape = [1, 1, 1, x.shape[-1]]
6282 6283 6284
        else:
            alpha_shape = [1, x.shape[1], 1, 1]

J
jerrywgz 已提交
6285
    elif mode == 'element':
6286 6287 6288
        assert (
            len(x.shape) >= 1
        ), "The size of input shape should be equal or larger than 1 in prelu() when mode is 'element'"
6289
        alpha_shape = [1] + list(x.shape)[1:]
J
jerrywgz 已提交
6290
    dtype = helper.input_dtype(input_param_name='x')
6291 6292 6293 6294 6295 6296 6297
    alpha = helper.create_parameter(
        attr=helper.param_attr,
        shape=alpha_shape,
        dtype=dtype,
        is_bias=False,
        default_initializer=Constant(0.25),
    )
6298 6299 6300
    if in_dygraph_mode():
        return _C_ops.prelu(x, alpha, data_format, mode)

X
Xin Pan 已提交
6301
    out = helper.create_variable_for_type_inference(dtype)
6302 6303 6304 6305 6306 6307
    helper.append_op(
        type="prelu",
        inputs={"X": x, 'Alpha': alpha},
        attrs={"mode": mode, "data_format": data_format},
        outputs={"Out": out},
    )
6308 6309 6310
    return out


G
fix  
gongweibao 已提交
6311 6312 6313
from paddle.fluid.framework import convert_np_dtype_to_dtype_


6314
@deprecated(since="2.0.0", update_to="paddle.normal")
G
gongweibao 已提交
6315
@templatedoc()
6316 6317 6318
def gaussian_random(
    shape, mean=0.0, std=1.0, seed=0, dtype='float32', name=None
):
G
fix  
gongweibao 已提交
6319
    """
6320 6321
    This OP returns a Tensor filled with random values sampled from a Gaussian
    distribution, with ``shape`` and ``dtype``.
G
fix  
gongweibao 已提交
6322 6323

    Args:
6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338
        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 已提交
6339 6340

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

6344
    Examples:
6345
       .. code-block:: python
6346

6347
            import paddle
6348
            import paddle.fluid as fluid
6349
            paddle.enable_static()
6350 6351

            # example 1:
6352
            # attr shape is a list which doesn't contain Tensor.
6353
            result_1 = fluid.layers.gaussian_random(shape=[3, 4])
6354 6355 6356
            # [[-0.31261674,  1.8736548,  -0.6274357,   0.96988016],
            #  [-0.12294637,  0.9554768,   1.5690808,  -1.2894802 ],
            #  [-0.60082096, -0.61138713,  1.5345167,  -0.21834975]]
6357 6358

            # example 2:
6359 6360 6361
            # 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)
6362
            result_2 = fluid.layers.gaussian_random(shape=[dim_1, dim_2])
6363 6364
            # [[ 0.51398206, -0.3389769,   0.23597084],
            #  [ 1.0388143,  -1.2015356,  -1.0499583 ]]
6365 6366

            # example 3:
6367
            # attr shape is a Tensor, the data type must be int64 or int32.
6368 6369
            var_shape = fluid.data(name='var_shape', shape=[2], dtype="int64")
            result_3 = fluid.layers.gaussian_random(var_shape)
6370 6371 6372 6373
            # if var_shape's value is [2, 3]
            # result_3 is:
            # [[-0.12310527,  0.8187662,   1.923219  ]
            #  [ 0.70721835,  0.5210541,  -0.03214082]]
6374

6375
       .. code-block:: python
6376

6377 6378
           # declarative mode
           # required: skiptest
6379 6380
           import numpy as np
           from paddle import fluid
6381

6382
           x = fluid.layers.gaussian_random((2, 3), std=2., seed=10)
6383

6384 6385 6386 6387
           place = fluid.CPUPlace()
           exe = fluid.Executor(place)
           start = fluid.default_startup_program()
           main = fluid.default_main_program()
6388

6389 6390
           exe.run(start)
           x_np, = exe.run(main, feed={}, fetch_list=[x])
6391

6392 6393 6394 6395 6396 6397 6398 6399 6400 6401
           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
6402

6403 6404 6405
           place = fluid.CPUPlace()
           with dg.guard(place) as g:
               x = fluid.layers.gaussian_random((2, 4), mean=2., dtype="float32", seed=10)
6406
               x_np = x.numpy()
6407 6408 6409
           x_np
           # array([[2.3060477 , 2.676496  , 3.9911983 , 0.9990833 ],
           #        [2.8675377 , 2.2279181 , 0.79029655, 2.8447366 ]], dtype=float32)
G
fix  
gongweibao 已提交
6410
    """
6411 6412
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
6413

6414 6415 6416
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
        place = _current_expected_place()
6417
        return _C_ops.gaussian(
6418 6419
            shape, float(mean), float(std), seed, dtype, place
        )
6420 6421

    if _in_legacy_dygraph():
6422
        shape = utils.convert_shape_to_list(shape)
6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434
        return _legacy_C_ops.gaussian_random(
            'shape',
            shape,
            'mean',
            float(mean),
            'std',
            float(std),
            'seed',
            seed,
            'dtype',
            dtype,
        )
6435 6436 6437

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

    inputs = {}
6440 6441 6442 6443
    attrs = {
        'mean': mean,
        'std': std,
        'seed': seed,
6444
        'dtype': dtype,
6445
        'use_mkldnn': False,
6446
    }
6447 6448 6449
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='gaussian_random/randn'
    )
6450

6451 6452
    helper = LayerHelper('gaussian_random', **locals())
    out = helper.create_variable_for_type_inference(dtype)
6453 6454 6455
    helper.append_op(
        type='gaussian_random', inputs=inputs, outputs={'Out': out}, attrs=attrs
    )
G
fix  
gongweibao 已提交
6456 6457 6458 6459

    return out


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

R
ruri 已提交
6465 6466 6467 6468
    Parameters:
        x (Variable): 2-D tensor, [batch_size, input_feature_dimensions]
        min (Float): minimum , default 0.0.
        max (Float): maximum, default 1.0.
6469
        seed (Float): Random seed, default 0. if seed is not 0, will generate same number every time.
G
fix  
gongweibao 已提交
6470
        dtype(np.dtype|core.VarDesc.VarType|str): The type of output data : float32, float_16, int etc
G
fix  
gongweibao 已提交
6471 6472

    Returns:
R
ruri 已提交
6473
        Variable: sampling tensor.
G
fix  
gongweibao 已提交
6474

6475 6476 6477
    Examples:
        .. code-block:: python

6478
            import paddle.fluid as fluid
R
ruri 已提交
6479
            x = fluid.data(
6480 6481
                name="X",
                shape=[13, 11],
R
ruri 已提交
6482
                dtype='float32')
6483

Y
Yibing Liu 已提交
6484
            out = fluid.layers.sampling_id(x)
G
fix  
gongweibao 已提交
6485 6486 6487
    """

    helper = LayerHelper('sampling_id', **locals())
X
Xin Pan 已提交
6488
    out = helper.create_variable_for_type_inference(dtype)
6489 6490 6491 6492 6493 6494
    helper.append_op(
        type='sampling_id',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'min': min, 'max': max, 'seed': seed},
    )
G
fix  
gongweibao 已提交
6495 6496 6497 6498

    return out


G
gongweibao 已提交
6499
@templatedoc()
X
Xin Pan 已提交
6500
def sum(x):
G
fix  
gongweibao 已提交
6501
    """
G
gongweibao 已提交
6502
    ${comment}
6503

6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532
    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 已提交
6533 6534

    Args:
6535
        x (Variable|list(Variable)): ${x_comment}
G
fix  
gongweibao 已提交
6536 6537

    Returns:
6538
        Variable: ${out_comment}
6539 6540 6541 6542

    Examples:
        .. code-block:: python

6543
            import paddle.fluid as fluid
6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562

            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.
6563 6564
            # 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,
6565
            #       and '__int64' on Windows. They both represent 64-bit integer variables.
G
fix  
gongweibao 已提交
6566 6567
    """

S
Steffy-zxf 已提交
6568
    return paddle.add_n(x)
G
fix  
gongweibao 已提交
6569 6570


G
gongweibao 已提交
6571
@templatedoc()
G
fix  
gongweibao 已提交
6572 6573
def slice(input, axes, starts, ends):
    """
6574
    This operator produces a slice of ``input`` along multiple axes. Similar to numpy:
6575
    https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html
6576 6577 6578 6579 6580 6581 6582
    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.
6583
    For slicing to the end of a dimension with unknown size, it is recommended
6584
    to pass in INT_MAX. The size of ``axes`` must be equal to ``starts`` and ``ends``.
6585 6586 6587
    Following examples will explain how slice works:

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

6589 6590 6591 6592 6593 6594 6595 6596
        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], ]
6597

6598 6599 6600 6601 6602
        Case2:
            Given:
                data = [ [1, 2, 3, 4], [5, 6, 7, 8], ]
                axes = [0, 1]
                starts = [0, 1]
6603
                ends = [-1, 1000]       # -1 denotes the reverse 0th position of dimension 0.
6604
            Then:
6605
                result = [ [2, 3, 4], ] # result = data[0:1, 1:4]
6606

G
fix  
gongweibao 已提交
6607
    Args:
T
Thunderbrook 已提交
6608
        input (Tensor): A ``Tensor`` . The data type is ``float16``, ``float32``, ``float64``, ``int32`` or ``int64``.
6609
        axes (list|tuple): The data type is ``int32`` . Axes that `starts` and `ends` apply to .
T
Thunderbrook 已提交
6610 6611
        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.
6612
                It represents starting indices of corresponding axis in ``axes``.
T
Thunderbrook 已提交
6613 6614
        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 .
6615
                It represents ending indices of corresponding axis in ``axes``.
G
fix  
gongweibao 已提交
6616 6617

    Returns:
T
Thunderbrook 已提交
6618
        Tensor:  A ``Tensor``. The data type is same as ``input``.
6619 6620

    Raises:
T
Thunderbrook 已提交
6621 6622
        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 已提交
6623

6624 6625 6626
    Examples:
        .. code-block:: python

T
Thunderbrook 已提交
6627
            import paddle
6628

T
Thunderbrook 已提交
6629
            input = paddle.rand(shape=[4, 5, 6], dtype='float32')
6630
            # example 1:
T
Thunderbrook 已提交
6631
            # attr starts is a list which doesn't contain tensor.
6632 6633 6634
            axes = [0, 1, 2]
            starts = [-3, 0, 2]
            ends = [3, 2, 4]
T
Thunderbrook 已提交
6635
            sliced_1 = paddle.slice(input, axes=axes, starts=starts, ends=ends)
6636
            # sliced_1 is input[0:3, 0:2, 2:4].
6637 6638

            # example 2:
T
Thunderbrook 已提交
6639 6640 6641
            # 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)
6642
            # sliced_2 is input[0:3, 0:2, 2:4].
G
fix  
gongweibao 已提交
6643
    """
6644
    if in_dygraph_mode():
6645 6646 6647
        attrs = ()
        starts_tensor = None
        ends_tensor = None
6648 6649

        if isinstance(axes, (list, tuple)):
6650
            axes = list(axes)
6651 6652
            if len(axes) == 0:
                raise ValueError(
6653 6654
                    "Input axes should not be an empty list/tuple."
                )
6655 6656 6657 6658 6659 6660 6661 6662
            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(
6663 6664 6665 6666
                "Input axes must be a python list or tuple, but reveived {}".format(
                    type(axes)
                )
            )
6667

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

J
Jiabin Yang 已提交
6670
        tmp_tensor_type = core.eager.Tensor
6671
        if isinstance(starts, (list, tuple)):
6672
            starts = [
6673
                item.numpy().item(0)
6674 6675
                if isinstance(item, tmp_tensor_type)
                else item
6676 6677
                for item in starts
            ]
6678
        elif isinstance(starts, tmp_tensor_type):
H
hong 已提交
6679 6680
            tensor_t = starts.numpy()
            starts = [ele for ele in tensor_t]
6681 6682

        if isinstance(ends, (list, tuple)):
6683
            ends = [
6684
                item.numpy().item(0)
6685 6686 6687
                if isinstance(item, tmp_tensor_type)
                else item
                for item in ends
6688
            ]
6689
            attrs += ('ends', ends)
6690
        elif isinstance(ends, tmp_tensor_type):
H
hong 已提交
6691 6692
            tensor_t = ends.numpy()
            ends = [ele for ele in tensor_t]
6693

6694
        return _C_ops.slice(input, axes, starts, ends, infer_flags, [])
J
Jiabin Yang 已提交
6695 6696 6697 6698 6699 6700 6701 6702 6703 6704
    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(
6705 6706
                        "Input axes should not be an empty list/tuple."
                    )
J
Jiabin Yang 已提交
6707 6708 6709 6710 6711 6712 6713 6714
                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(
6715 6716 6717 6718
                    "Input axes must be a python list or tuple, but reveived {}".format(
                        type(axes)
                    )
                )
J
Jiabin Yang 已提交
6719 6720 6721 6722 6723 6724 6725 6726

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

            tmp_tensor_type = Variable

            if isinstance(starts, (list, tuple)):
                starts = [
                    item.numpy().item(0)
6727 6728
                    if isinstance(item, tmp_tensor_type)
                    else item
J
Jiabin Yang 已提交
6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739
                    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)
6740 6741
                    if isinstance(item, tmp_tensor_type)
                    else item
J
Jiabin Yang 已提交
6742 6743 6744 6745 6746 6747 6748 6749
                    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)))

6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761
            return _legacy_C_ops.slice(
                input,
                starts_tensor,
                ends_tensor,
                None,
                None,
                'axes',
                axes,
                'infer_flags',
                infer_flags,
                *attrs,
            )
6762

6763 6764
    if not isinstance(starts, (list, tuple, Variable)):
        raise ValueError(
6765 6766
            "Input starts must be an Variable, python list or tuple."
        )
6767 6768
    if not isinstance(ends, (list, tuple, Variable)):
        raise ValueError(
6769 6770
            "Input ends must be an Variable, python list or tuple."
        )
6771

G
fix  
gongweibao 已提交
6772
    helper = LayerHelper('slice', **locals())
6773 6774 6775 6776 6777

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

6778 6779 6780 6781 6782 6783 6784
    # 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 已提交
6785
        if utils._contain_var(starts):
6786
            inputs['StartsTensorList'] = utils._convert_to_tensor_list(starts)
6787 6788 6789 6790 6791 6792
            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 已提交
6793 6794
        else:
            attrs['starts'] = starts
6795 6796 6797 6798 6799 6800 6801 6802

    # 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 已提交
6803
        if utils._contain_var(ends):
6804
            inputs['EndsTensorList'] = utils._convert_to_tensor_list(ends)
6805 6806 6807 6808 6809 6810
            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 已提交
6811 6812 6813
        else:
            attrs['ends'] = ends

6814 6815
    # infer_flags
    attrs['infer_flags'] = infer_flags
X
Xin Pan 已提交
6816
    out = helper.create_variable_for_type_inference(
6817 6818 6819 6820 6821
        dtype=helper.input_dtype('input')
    )
    helper.append_op(
        type='slice', inputs=inputs, attrs=attrs, outputs={'Out': out}
    )
G
fix  
gongweibao 已提交
6822 6823 6824 6825 6826 6827

    return out


def shape(input):
    """
6828
    :alias_main: paddle.shape
6829 6830
        :alias: paddle.shape,paddle.tensor.shape,paddle.tensor.attribute.shape
        :old_api: paddle.fluid.layers.shape
6831

C
chengduozh 已提交
6832 6833
    **Shape Layer**

C
fix doc  
chengduozh 已提交
6834
    Get the shape of the input.
G
fix  
gongweibao 已提交
6835

6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852
    .. 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 已提交
6853
    Args:
6854
        input (Variable): The input can be N-D Tensor or SelectedRows with data type bool, float16, float32, float64, int32, int64.
6855
                          If input variable is type of SelectedRows, returns the shape of it's inner tensor.
G
fix  
gongweibao 已提交
6856 6857

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

6860 6861 6862
    Examples:
        .. code-block:: python

6863
            import paddle.fluid as fluid
6864
            import numpy as np
W
Wilber 已提交
6865 6866
            import paddle
            paddle.enable_static()
6867

6868
            inputs = fluid.data(name="x", shape=[3, 100, 100], dtype="float32")
6869 6870 6871 6872 6873 6874 6875 6876 6877
            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 已提交
6878
    """
6879
    if in_dygraph_mode():
6880
        out = _C_ops.shape(input)
6881 6882 6883
        out.stop_gradient = True
        return out
    if _in_legacy_dygraph():
6884
        out = _legacy_C_ops.shape(input)
W
Wilber 已提交
6885 6886 6887
        out.stop_gradient = True
        return out

6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902
    check_variable_and_dtype(
        input,
        'input',
        [
            'bool',
            'float16',
            'float32',
            'float64',
            'int32',
            'int64',
            'complex64',
            'complex128',
        ],
        'shape',
    )
G
fix  
gongweibao 已提交
6903
    helper = LayerHelper('shape', **locals())
6904
    out = helper.create_variable_for_type_inference(dtype='int32')
6905 6906 6907 6908 6909 6910
    helper.append_op(
        type='shape',
        inputs={'Input': input},
        outputs={'Out': out},
        stop_gradient=True,
    )
G
fix  
gongweibao 已提交
6911 6912

    return out
G
merge  
gongweibao 已提交
6913 6914


6915
@deprecated(since="2.0.0", update_to="paddle.numel")
Z
zhoukunsheng 已提交
6916 6917 6918 6919 6920 6921 6922
def size(input):
    """
    **Size Layer**

    Returns the number of elements for a tensor, which is a int64 Tensor with shape [1].

    Args:
6923
        input (Tensor): The input Tensor, it's data type can be bool, float16, float32, float64, int32, int64.
Z
zhoukunsheng 已提交
6924 6925

    Returns:
6926
        Tensor: The number of elements for the input Tensor.
Z
zhoukunsheng 已提交
6927

6928 6929
    Raises:
        TypeError: ``input`` must be a Tensor and the data type of ``input`` must be one of bool, float16, float32, float64, int32, int64.
6930

Z
zhoukunsheng 已提交
6931 6932 6933
    Examples:
        .. code-block:: python

6934
            import paddle
Z
zhoukunsheng 已提交
6935
            import paddle.fluid.layers as layers
6936
            paddle.enable_static()
Z
zhoukunsheng 已提交
6937 6938 6939 6940 6941 6942

            input = layers.data(
                name="input", shape=[3, 100], dtype="float32", append_batch_size=False)
            rank = layers.size(input) # 300
    """

H
hong 已提交
6943
    if in_dygraph_mode():
6944
        return _C_ops.numel(input)
H
hong 已提交
6945 6946

    if _in_legacy_dygraph():
6947
        return _legacy_C_ops.size(input)
H
hong 已提交
6948

6949
    check_variable_and_dtype(
6950 6951 6952 6953 6954
        input,
        'input',
        ['bool', 'float16', 'float32', 'float64', 'int32', 'int64'],
        "size",
    )
Z
zhoukunsheng 已提交
6955 6956 6957 6958 6959 6960 6961
    helper = LayerHelper('size', **locals())
    out = helper.create_variable_for_type_inference(dtype='int64')
    helper.append_op(type='size', inputs={'Input': input}, outputs={'Out': out})

    return out


S
sneaxiy 已提交
6962 6963 6964 6965
def _elementwise_op(helper):
    op_type = helper.layer_type
    x = helper.kwargs.get('x', None)
    y = helper.kwargs.get('y', None)
X
Xin Pan 已提交
6966

S
sneaxiy 已提交
6967 6968
    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)
6969
    check_variable_and_dtype(
6970 6971 6972 6973 6974
        x,
        'x',
        ['float16', 'uint16', 'float32', 'float64', 'int32', 'int64'],
        op_type,
    )
6975
    check_variable_and_dtype(
6976 6977 6978 6979 6980
        y,
        'y',
        ['float16', 'uint16', 'float32', 'float64', 'int32', 'int64'],
        op_type,
    )
6981

S
sneaxiy 已提交
6982 6983
    axis = helper.kwargs.get('axis', -1)
    use_mkldnn = helper.kwargs.get('use_mkldnn', False)
S
sneaxiy 已提交
6984
    name = helper.kwargs.get('name', None)
6985
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
S
sneaxiy 已提交
6986

6987 6988 6989 6990 6991 6992
    helper.append_op(
        type=op_type,
        inputs={'X': x, 'Y': y},
        outputs={'Out': out},
        attrs={'axis': axis, 'use_mkldnn': use_mkldnn},
    )
S
sneaxiy 已提交
6993 6994 6995
    return helper.append_activation(out)


X
Xin Pan 已提交
6996
def elementwise_add(x, y, axis=-1, act=None, name=None):
6997
    """
6998

6999
    Examples:
7000

7001
        .. code-block:: python
7002

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

7017 7018 7019 7020
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
7021

7022
            print(z_value) # [3., 8., 6.]
7023 7024


7025
        .. code-block:: python
7026

7027 7028 7029
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7030

7031 7032 7033 7034 7035 7036 7037 7038 7039 7040
            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
7041

7042 7043
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
7044

7045 7046
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
7047

7048
            print(z_value) # z.shape=[2,3,4,5]
7049 7050


7051
        ..  code-block:: python
7052

7053 7054 7055
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7056

7057 7058 7059 7060 7061 7062 7063 7064 7065 7066
            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
7067

7068 7069
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
7070

7071 7072 7073
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
7074 7075

    """
J
Jiabin Yang 已提交
7076
    if _non_static_mode():
7077
        return _elementwise_op_in_dygraph(
7078 7079 7080 7081 7082
            x,
            y,
            axis=axis,
            act=act,
            op_name='elementwise_add',
7083 7084
            use_mkldnn=_global_flags()["FLAGS_use_mkldnn"],
        )
7085

S
sneaxiy 已提交
7086 7087 7088
    return _elementwise_op(LayerHelper('elementwise_add', **locals()))


7089
@deprecated(since="2.0.0", update_to="paddle.divide")
X
Xin Pan 已提交
7090
def elementwise_div(x, y, axis=-1, act=None, name=None):
7091
    """
7092

7093
    Examples:
7094

7095
        .. code-block:: python
7096

7097 7098 7099
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7100

7101 7102 7103 7104 7105 7106 7107 7108 7109 7110
            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
7111

7112 7113 7114 7115
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
7116

7117
            print(z_value) # [2., 0.6, 2.]
7118 7119


7120
        .. code-block:: python
7121

7122 7123 7124
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7125

7126 7127 7128 7129 7130 7131 7132 7133 7134 7135
            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
7136

7137 7138
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
7139

7140 7141
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
7142

7143
            print(z_value) # z.shape=[2,3,4,5]
7144 7145


7146
        ..  code-block:: python
7147

7148 7149 7150
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7151

7152 7153 7154 7155 7156 7157 7158 7159 7160 7161
            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
7162

7163 7164
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
7165

7166 7167 7168
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
7169 7170

    """
J
Jiabin Yang 已提交
7171
    if _non_static_mode():
7172 7173 7174
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_div'
        )
7175

S
sneaxiy 已提交
7176 7177 7178
    return _elementwise_op(LayerHelper('elementwise_div', **locals()))


X
Xin Pan 已提交
7179
def elementwise_sub(x, y, axis=-1, act=None, name=None):
7180
    """
7181

7182
    Examples:
7183

7184
        .. code-block:: python
7185

7186 7187 7188
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7189

7190 7191 7192 7193 7194 7195 7196 7197 7198 7199
            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
7200

7201 7202 7203 7204
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
7205

7206
            print(z_value) # [1., -2., 2.]
7207 7208


7209
        .. code-block:: python
7210

7211 7212 7213
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7214

7215 7216 7217 7218 7219 7220 7221 7222 7223 7224
            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
7225

7226 7227
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
7228

7229 7230
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
7231

7232
            print(z_value) # z.shape=[2,3,4,5]
7233 7234


7235
        ..  code-block:: python
7236

7237 7238 7239
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7240

7241 7242 7243 7244 7245 7246 7247 7248 7249 7250
            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
7251

7252 7253
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
7254

7255 7256 7257
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
7258 7259

    """
J
Jiabin Yang 已提交
7260
    if _non_static_mode():
7261 7262 7263
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_sub'
        )
7264

S
sneaxiy 已提交
7265 7266 7267
    return _elementwise_op(LayerHelper('elementwise_sub', **locals()))


7268
@deprecated(since="2.0.0", update_to="paddle.multiply")
X
Xin Pan 已提交
7269
def elementwise_mul(x, y, axis=-1, act=None, name=None):
7270
    """
7271

7272
    Examples:
7273

7274
        .. code-block:: python
7275

7276 7277 7278
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7279

7280 7281 7282 7283 7284 7285 7286 7287 7288 7289
            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
7290

7291 7292 7293 7294
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
7295

7296
            print(z_value) # [2., 15., 8.]
7297 7298


7299
        .. code-block:: python
7300

7301 7302 7303
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7304

7305 7306 7307 7308 7309 7310 7311 7312 7313 7314
            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
7315

7316 7317
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
7318

7319 7320
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
7321

7322
            print(z_value) # z.shape=[2,3,4,5]
7323 7324


7325
        ..  code-block:: python
7326

7327 7328 7329
            import paddle.fluid as fluid
            import numpy as np
            import paddle
7330

7331 7332 7333 7334 7335 7336 7337 7338 7339 7340
            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
7341

7342 7343
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
7344

7345 7346 7347
            z_value = exe.run(feed=gen_data(),
                                fetch_list=[z.name])
            print(z_value) # z.shape=[2,3,4,5]
7348

7349
    """
J
Jiabin Yang 已提交
7350
    if _non_static_mode():
7351 7352 7353
        return _elementwise_op_in_dygraph(
            x, y, axis=axis, act=act, op_name='elementwise_mul'
        )
7354

S
sneaxiy 已提交
7355 7356 7357 7358
    return _elementwise_op(LayerHelper('elementwise_mul', **locals()))


for func in [
7359 7360 7361 7362
    elementwise_add,
    elementwise_div,
    elementwise_sub,
    elementwise_mul,
7363 7364
]:
    op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
7365 7366

    # insert the c++ doc string on top of python doc string
7367 7368 7369 7370 7371
    func.__doc__ = (
        _generate_doc_string_(
            op_proto,
            additional_args_lines=[
                "axis (int32, optional): If X.dimension != Y.dimension, \
7372 7373
            Y.dimension must be a subsequence of x.dimension. \
            And axis is the start dimension index for broadcasting Y onto X. ",
7374
                "act (string, optional): Activation applied to the output. \
7375
            Default is None. Details: :ref:`api_guide_activations_en` ",
7376
                "name (string, optional): Name of the output. \
7377
            Default is None. It's used to print debug info for developers. Details: \
7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393
            :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__)
    )
7394

7395 7396 7397
    doc_list = func.__doc__.splitlines()

    for idx, val in enumerate(doc_list):
7398 7399 7400 7401 7402
        if (
            val.startswith("Warning: ")
            and val.endswith(" instead.")
            and "and will be removed in future versions." in val
        ):
7403 7404 7405 7406
            doc_list.insert(0, doc_list.pop(idx))
            func.__doc__ = "\n" + "\n".join(i for i in doc_list)
            break

7407
for func in []:
S
sneaxiy 已提交
7408 7409 7410 7411
    op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
    func.__doc__ = _generate_doc_string_(
        op_proto,
        additional_args_lines=[
S
sneaxiy 已提交
7412
            "act (basestring|None): Activation applied to the output.",
7413 7414 7415 7416 7417 7418
            "name (basestring|None): Name of the output.",
        ],
    )
    func.__doc__ = (
        func.__doc__
        + """
7419 7420 7421

Examples:
  .. code-block:: python
7422

7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452
    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)
7453 7454 7455 7456 7457 7458 7459 7460 7461 7462
    """
        % (
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
            func.__name__,
        )
    )
M
minqiyang 已提交
7463 7464


7465
def _logical_op(op_name, x, y, out=None, name=None, binary_op=True):
J
Jiabin Yang 已提交
7466
    if _non_static_mode():
7467
        op = getattr(_legacy_C_ops, op_name)
7468 7469 7470 7471
        if binary_op:
            return op(x, y)
        else:
            return op(x)
7472
    check_variable_and_dtype(
7473 7474
        x,
        "x",
7475
        ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
7476 7477
        op_name,
    )
7478
    if y is not None:
7479
        check_variable_and_dtype(
7480 7481
            y,
            "y",
7482
            ["bool", "int8", "int16", "int32", "int64", "float32", "float64"],
7483 7484
            op_name,
        )
7485
    if out is not None:
7486
        check_type(out, "out", Variable, op_name)
7487

M
minqiyang 已提交
7488 7489
    helper = LayerHelper(op_name, **locals())

7490 7491 7492
    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."
7493 7494
            % (op_name, x.dtype, y.dtype)
        )
M
minqiyang 已提交
7495 7496

    if out is None:
7497
        out = helper.create_variable_for_type_inference(dtype=x.dtype)
M
minqiyang 已提交
7498 7499

    if binary_op:
7500 7501 7502
        helper.append_op(
            type=op_name, inputs={"X": x, "Y": y}, outputs={"Out": out}
        )
M
minqiyang 已提交
7503 7504 7505 7506 7507 7508
    else:
        helper.append_op(type=op_name, inputs={"X": x}, outputs={"Out": out})

    return out


7509 7510 7511
@templatedoc()
def clip(x, min, max, name=None):
    """
7512
        :old_api: paddle.fluid.layers.clip
7513

7514 7515 7516 7517
    ${comment}

    Args:
        x(${x_type}): ${x_comment}
S
SunGaofeng 已提交
7518 7519
        min(float): ${min_comment}
        max(float): ${max_comment}
7520 7521
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
7522
                             For more information, please refer to :ref:`api_guide_Name`
7523 7524

    Returns:
S
SunGaofeng 已提交
7525 7526 7527 7528
        ${out_comment}

    Return Type:
        ${out_type}
7529 7530 7531 7532

    Examples:
        .. code-block:: python

S
SunGaofeng 已提交
7533
            import paddle.fluid as fluid
S
SunGaofeng 已提交
7534
            input = fluid.data(
7535 7536
                name='data', shape=[1], dtype='float32')
            reward = fluid.layers.clip(x=input, min=-1.0, max=1.0)
7537 7538 7539
    """

    helper = LayerHelper("clip", **locals())
7540
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'clip')
7541 7542

    if name is None:
7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556
        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},
    )
7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568

    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}
7569 7570 7571
        name(str, optional): For detailed information, please refer
            to :ref:`api_guide_Name`. Usually name is no need to set and
            None by default.
7572 7573

    Returns:
7574
        Tensor:
W
wangguanzhong 已提交
7575

7576
        out(${out_type}): ${out_comment}
7577

W
wangguanzhong 已提交
7578

7579 7580 7581
    Examples:
        .. code-block:: python

7582
            import paddle
7583
            import paddle.fluid as fluid
7584

7585 7586 7587
            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]]
7588 7589
    """

L
lyq 已提交
7590
    if in_dygraph_mode():
7591
        return _C_ops.clip_by_norm(x, max_norm)
J
Jiabin Yang 已提交
7592
    if _non_static_mode():
7593
        return _legacy_C_ops.clip_by_norm(x, 'max_norm', max_norm)
7594

7595
    helper = LayerHelper("clip_by_norm", **locals())
7596
    check_variable_and_dtype(x, 'X', ['float32', 'float16'], 'clip_by_norm')
7597
    check_type(max_norm, 'max_norm', (float), 'clip_by_norm')
7598 7599

    if name is None:
7600 7601 7602
        name = unique_name.generate_with_ignorable_key(
            ".".join([helper.name, 'tmp'])
        )
S
sneaxiy 已提交
7603

7604 7605 7606
    out = helper.create_variable(
        type=x.type, name=name, dtype=x.dtype, persistable=False
    )
7607

7608 7609 7610 7611 7612 7613
    helper.append_op(
        type="clip_by_norm",
        inputs={"X": x},
        attrs={"max_norm": max_norm},
        outputs={"Out": out},
    )
7614 7615

    return out
X
Xin Pan 已提交
7616 7617


7618
@deprecated(since="2.0.0", update_to="paddle.mean")
X
Xin Pan 已提交
7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629
@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}
7630 7631 7632 7633

    Examples:
        .. code-block:: python

7634
            import paddle
7635
            import paddle.fluid as fluid
7636 7637
            paddle.enable_static()

7638 7639
            input = fluid.layers.data(
                name='data', shape=[2, 3], dtype='float32')
7640
            mean = paddle.mean(input)
X
Xin Pan 已提交
7641
    """
7642

7643
    if _in_legacy_dygraph():
7644
        return _legacy_C_ops.mean(x)
7645
    if in_dygraph_mode():
7646
        return _C_ops.mean_all(x)
X
Xin Pan 已提交
7647 7648

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

7652 7653 7654
    helper.append_op(
        type="mean", inputs={"X": x}, attrs={}, outputs={"Out": out}
    )
X
Xin Pan 已提交
7655 7656 7657 7658

    return out


C
chengduo 已提交
7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669
@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}
7670 7671 7672 7673

    Examples:
        .. code-block:: python

7674
            import paddle.fluid as fluid
7675 7676 7677 7678 7679
            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 已提交
7680
    """
7681 7682 7683
    if in_dygraph_mode():
        return _C_ops.merge_selected_rows(x)

7684
    if _non_static_mode():
7685
        return _legacy_C_ops.merge_selected_rows(x)
C
chengduo 已提交
7686 7687 7688

    helper = LayerHelper("merge_selected_rows", **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
7689 7690 7691 7692 7693 7694
    helper.append_op(
        type="merge_selected_rows",
        inputs={"X": x},
        attrs={},
        outputs={"Out": out},
    )
C
chengduo 已提交
7695 7696 7697
    return out


X
Xin Pan 已提交
7698 7699
def mul(x, y, x_num_col_dims=1, y_num_col_dims=1, name=None):
    """
L
liu zhengxi 已提交
7700 7701 7702 7703 7704 7705 7706 7707
    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 已提交
7708 7709

    Args:
L
liu zhengxi 已提交
7710 7711
        x (Variable): The first input Tensor/LoDTensor of mul_op.
        y (Variable): The second input Tensor/LoDTensor of mul_op.
7712 7713 7714
        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 已提交
7715 7716

    Returns:
L
liu zhengxi 已提交
7717
        Variable(Tensor/LoDTensor): The output Tensor/LoDTensor of mul op.
7718 7719

    Examples:
L
liu zhengxi 已提交
7720
        ..  code-block:: python
7721

7722
            import paddle.fluid as fluid
7723 7724
            import paddle
            paddle.enable_static()
7725 7726 7727 7728 7729
            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)
7730

7731

X
Xin Pan 已提交
7732
    """
J
Jiabin Yang 已提交
7733
    if _non_static_mode():
7734 7735 7736 7737 7738 7739 7740 7741
        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 已提交
7742

7743 7744
    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 已提交
7745
    helper = LayerHelper("mul", **locals())
7746 7747
    check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'mul')
    check_variable_and_dtype(y, 'y', ['float16', 'float32', 'float64'], 'mul')
7748
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
X
Xin Pan 已提交
7749

7750 7751 7752
    helper.append_op(
        type="mul", inputs={"X": x, "Y": y}, attrs=attrs, outputs={"Out": out}
    )
X
Xin Pan 已提交
7753 7754 7755
    return out


7756
@deprecated(since="2.0.0", update_to="paddle.nn.functional.maxout")
X
Xin Pan 已提交
7757
@templatedoc()
7758
def maxout(x, groups, name=None, axis=1):
X
Xin Pan 已提交
7759 7760 7761 7762 7763
    """
    ${comment}

    Args:
        x(${x_type}): ${x_comment}
7764 7765
        groups(int): ${groups_comment}
        axis(int, optional): ${axis_comment}
7766 7767
        name(str, optional): For detailed information, please refer
            to :ref:`api_guide_Name`. Usually name is no need to set and
W
wangguanzhong 已提交
7768
            None by default.
X
Xin Pan 已提交
7769 7770

    Returns:
7771
        Variable: ${out_comment}
J
jerrywgz 已提交
7772

7773 7774
    Raises:
        ValueError: If `axis` is not 1, -1 or 3.
7775
        ValueError: If the number of input channels can not be divisible by `groups`.
W
wangguanzhong 已提交
7776

J
jerrywgz 已提交
7777 7778 7779
    Examples:
        .. code-block:: python

7780
            import paddle.fluid as fluid
7781 7782 7783
            import paddle
            paddle.enable_static()

7784
            input = fluid.data(
7785 7786
                name='data',
                shape=[None, 256, 32, 32],
J
jerrywgz 已提交
7787 7788
                dtype='float32')
            out = fluid.layers.maxout(input, groups=2)
X
Xin Pan 已提交
7789
    """
7790
    return paddle.nn.functional.maxout(**locals())
7791 7792


J
JiabinYang 已提交
7793
def space_to_depth(x, blocksize, name=None):
7794
    r"""
7795

J
JiabinYang 已提交
7796
    Gives a blocksize to space_to_depth the input LoDtensor with Layout: [batch, channel, height, width]
7797

7798 7799 7800
    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 已提交
7801
    The attr blocksize indicates the input block size.
7802

T
tianshuo78520a 已提交
7803
    space_to_depth will reorganize the elements of input with shape[batch, channel, height, width] \
7804 7805
        according to blocksize to construct output with shape \
        [batch, channel * blocksize * blocksize, height/blocksize, width/blocksize]:
J
JiabinYang 已提交
7806

J
JiabinYang 已提交
7807 7808 7809 7810 7811
    - 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

7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828
    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 已提交
7829

J
JiabinYang 已提交
7830
    Args:
7831 7832 7833 7834 7835 7836
        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 已提交
7837

7838
    Returns:
7839
            Tensor, The output, which should be 4 dims Tensor or LodTensor, with the shape \
7840 7841
            [batch, channel * blocksize * blocksize, height/blocksize, width/blocksize]

J
JiabinYang 已提交
7842 7843
    Examples:
        .. code-block:: python
7844

7845 7846
            import paddle.fluid as fluid
            import numpy as np
7847 7848
            import numpy as np
            import paddle
J
JiabinYang 已提交
7849

7850
            paddle.enable_static()
7851 7852
            data = fluid.data(
                name='data', shape=[1, 4, 2, 2], dtype='float32')
J
JiabinYang 已提交
7853
            space_to_depthed = fluid.layers.space_to_depth(
J
JiabinYang 已提交
7854
                x=data, blocksize=2)
7855

7856
            exe = fluid.Executor(fluid.CPUPlace())
7857
            data_np = np.arange(0,16).reshape((1,4,2,2)).astype('float32')
7858 7859 7860 7861 7862 7863 7864

            print(data_np)
            #array([[[[ 0.,  1.], [ 2.,  3.]],
            #        [[ 4.,  5.], [ 6.,  7.]],
            #        [[ 8.,  9.], [10., 11.]],
            #        [[12., 13.], [14., 15.]]]], dtype=float32)

7865
            out_main = exe.run(fluid.default_main_program(),
7866 7867 7868 7869 7870 7871 7872 7873
                        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)]
7874

J
JiabinYang 已提交
7875 7876
    """

J
JiabinYang 已提交
7877
    helper = LayerHelper("space_to_depth", **locals())
J
JiabinYang 已提交
7878

J
JiabinYang 已提交
7879 7880
    if not (isinstance(blocksize, int)):
        raise ValueError("blocksize must be a python Int")
J
JiabinYang 已提交
7881

7882 7883 7884 7885 7886 7887
    check_variable_and_dtype(
        x,
        'x',
        ['float16', 'float32', 'float64', 'int32', 'int64'],
        'space_to_depth',
    )
X
xujiaqi01 已提交
7888

7889
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
J
JiabinYang 已提交
7890

7891 7892 7893 7894 7895 7896
    helper.append_op(
        type="space_to_depth",
        inputs={"X": x},
        attrs={"blocksize": blocksize},
        outputs={"Out": out},
    )
J
JiabinYang 已提交
7897 7898
    return out

J
JiabinYang 已提交
7899

7900 7901 7902
def affine_channel(
    x, scale=None, bias=None, data_layout='NCHW', name=None, act=None
):
7903
    """
7904

7905 7906 7907 7908
    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.
7909

7910 7911 7912
    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 已提交
7913
            is applied in the second dimension.The data type is float32 or float64.
7914 7915
        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 已提交
7916
            the input.The data type is float32 or float64.
7917 7918
        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 已提交
7919
            The data type is float32 or float64.
7920
        data_layout (str, optional): Specify the data format of the input, and the data format of the output
7921 7922
            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:
7923
            `[batch_size, input_channels, input_height, input_width]`. If input is 2D Tensor, you can ignore
7924
            data_layout.
L
LielinJiang 已提交
7925 7926
        name (str, default None): The name of this layer. For more information,
            please refer to :ref:`api_guide_Name` .
7927
        act (str, default None): Activation to be applied to the output of this layer.
7928 7929

    Returns:
L
LielinJiang 已提交
7930
        Variable: A tensor which has the same shape, data layout and data type with x.
B
Bai Yifan 已提交
7931 7932 7933

    Examples:
        .. code-block:: python
L
LielinJiang 已提交
7934 7935

            import numpy as np
B
Bai Yifan 已提交
7936
            import paddle.fluid as fluid
7937 7938
            import paddle.fluid as fluid
            import paddle
L
LielinJiang 已提交
7939

7940
            paddle.enable_static()
L
LielinJiang 已提交
7941 7942 7943 7944 7945 7946 7947 7948 7949
            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 已提交
7950
            out = fluid.layers.affine_channel(data,scale=input_scale,
L
LielinJiang 已提交
7951 7952 7953 7954 7955 7956 7957 7958 7959 7960
                                    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 已提交
7961

7962 7963
    """
    helper = LayerHelper("affine_channel", **locals())
7964 7965 7966
    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')
7967
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
7968

7969 7970 7971 7972 7973 7974
    helper.append_op(
        type="affine_channel",
        inputs={"X": x, 'Scale': scale, 'Bias': bias},
        attrs={"data_layout": data_layout},
        outputs={"Out": out},
    )
7975
    return helper.append_activation(out)
7976 7977


B
barrierye 已提交
7978
def similarity_focus(input, axis, indexes, name=None):
7979
    r"""
B
barrierye 已提交
7980
    SimilarityFocus Operator
B
barrierye 已提交
7981 7982

    Generate a similarity focus mask with the same shape of input using the following method:
M
minqiyang 已提交
7983

7984 7985 7986
    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 已提交
7987
       is (BatchSize, A, B, C), the shape of tensor T is (BatchSize, B, C).
7988 7989 7990 7991 7992 7993 7994
    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 已提交
7995
       each index.
B
barrierye 已提交
7996 7997 7998 7999
    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 已提交
8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048
    .. 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 已提交
8049
    Args:
8050
        input(Variable): The input tensor variable(default float). It should
8051
            be a 4-D tensor with shape [BatchSize, A, B, C]. Data type is
Y
Yibing Liu 已提交
8052
            float32 or float64.
B
barrierye 已提交
8053
        axis(int): Indicating the dimension to be selected. It can only be
B
barrierye 已提交
8054
            1, 2 or 3.
B
barrierye 已提交
8055
        indexes(list): Indicating the indexes of the selected dimension.
B
barrierye 已提交
8056 8057

    Returns:
H
haowang101779990 已提交
8058 8059
        Variable: A tensor variable with the same shape and same type \
                  as the input.
8060

B
barrierye 已提交
8061 8062
    Examples:
        .. code-block:: python
H
haowang101779990 已提交
8063

8064
            import paddle.fluid as fluid
8065 8066
            import paddle
            paddle.enable_static()
Y
Yibing Liu 已提交
8067
            data = fluid.data(
Y
Yibing Liu 已提交
8068 8069
                name='data', shape=[-1, 3, 2, 2], dtype='float32')
            fluid.layers.similarity_focus(input=data, axis=1, indexes=[0])
B
barrierye 已提交
8070 8071 8072
    """
    helper = LayerHelper('similarity_focus', **locals())
    # check attrs
8073 8074 8075
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], "similarity_focus"
    )
8076 8077
    check_type(axis, 'axis', int, "similarity_focus")
    check_type(indexes, 'indexes', list, "similarity_focus")
B
barrierye 已提交
8078 8079 8080 8081 8082
    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.")

8083
    out = helper.create_variable_for_type_inference(dtype=input.dtype)
8084 8085 8086 8087 8088 8089
    helper.append_op(
        type='similarity_focus',
        inputs={'X': input},
        outputs={'Out': out},
        attrs={"axis": axis, "indexes": indexes},
    )
B
barrierye 已提交
8090
    return out
B
barrierye 已提交
8091 8092


M
minqiyang 已提交
8093 8094
def hash(input, hash_size, num_hash=1, name=None):
    """
8095

Z
zhupengyang 已提交
8096
    This OP hash the input to an integer less than the hash_size.
M
minqiyang 已提交
8097 8098
    The hash algorithm we used was xxHash - Extremely fast hash algorithm
    (https://github.com/Cyan4973/xxHash/tree/v0.6.5)
M
minqiyang 已提交
8099 8100

    Args:
Z
zhupengyang 已提交
8101 8102 8103 8104 8105 8106
        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 已提交
8107 8108

    Returns:
Z
zhupengyang 已提交
8109
       Variable: A LoDTensor with the same data type as input.
M
minqiyang 已提交
8110 8111

    Examples:
Z
zhupengyang 已提交
8112
        .. code-block:: python
H
haowang101779990 已提交
8113

8114
            import paddle.fluid as fluid
Z
zhupengyang 已提交
8115
            import numpy as np
8116 8117
            import paddle
            paddle.enable_static()
8118

Z
zhupengyang 已提交
8119
            place = fluid.core.CPUPlace()
8120

8121 8122
            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)
8123

Z
zhupengyang 已提交
8124 8125 8126 8127
            exe = fluid.Executor(place)
            exe.run(fluid.default_startup_program())
            in1 = np.array([[1,2],[3,4]]).astype("int32")
            print(in1)
8128
            x_i = fluid.create_lod_tensor(in1, [[0, 2]], place)
Z
zhupengyang 已提交
8129 8130 8131 8132 8133 8134 8135 8136 8137 8138
            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 已提交
8139
    """
8140
    check_variable_and_dtype(input, 'input', ['int32', 'int64'], 'hash')
8141 8142
    check_type(hash_size, 'hash_size', int, 'hash')
    check_type(num_hash, 'num_hash', int, 'hash')
M
minqiyang 已提交
8143
    helper = LayerHelper('hash', **locals())
8144 8145 8146 8147 8148 8149 8150 8151 8152
    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 已提交
8153
    return out
G
gmcather 已提交
8154 8155


D
dengkaipeng 已提交
8156
@templatedoc()
8157 8158
def grid_sampler(x, grid, name=None):
    """
8159

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

H
haowang101779990 已提交
8169
    .. code-block:: text
8170

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

K
Kaipeng Deng 已提交
8174 8175 8176 8177
        .. code-block:: text

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

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

H
haowang101779990 已提交
8183 8184 8185 8186 8187 8188 8189 8190 8191
          wn ------- y_n ------- en
          |           |           |
          |          d_n          |
          |           |           |
         x_w --d_w-- grid--d_e-- x_e
          |           |           |
          |          d_s          |
          |           |           |
          ws ------- y_s ------- wn
8192

H
haowang101779990 已提交
8193 8194 8195 8196
        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
8197

H
haowang101779990 已提交
8198 8199 8200 8201
        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
8202

H
haowang101779990 已提交
8203 8204 8205 8206
        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
8207

H
haowang101779990 已提交
8208 8209
        output = wn * d_e * d_s + en * d_w * d_s
               + ws * d_e * d_n + es * d_w * d_n
D
dengkaipeng 已提交
8210 8211

    Args:
K
Kaipeng Deng 已提交
8212 8213 8214 8215 8216 8217 8218 8219 8220
        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 已提交
8221 8222

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

H
haowang101779990 已提交
8227 8228 8229 8230
    Examples:

        .. code-block:: python

K
Kaipeng Deng 已提交
8231
            import paddle.fluid as fluid
8232 8233
            import paddle.fluid as fluid
            import paddle
K
Kaipeng Deng 已提交
8234

8235
            paddle.enable_static()
K
Kaipeng Deng 已提交
8236 8237
            # use with affine_grid
            x = fluid.data(name='x', shape=[None, 10, 32, 32], dtype='float32')
K
Kaipeng Deng 已提交
8238 8239
            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 已提交
8240
            out = fluid.layers.grid_sampler(x=x, grid=grid)
8241

D
dengkaipeng 已提交
8242 8243 8244
    """
    helper = LayerHelper("grid_sampler", **locals())

8245
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'grid_sampler')
8246 8247 8248
    check_variable_and_dtype(
        grid, 'grid', ['float32', 'float64'], 'grid_sampler'
    )
D
dengkaipeng 已提交
8249 8250 8251 8252 8253 8254
    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")

8255
    out = helper.create_variable_for_type_inference(x.dtype)
D
dengkaipeng 已提交
8256 8257
    ipts = {'X': x, 'Grid': grid}

8258 8259
    attrs = {'use_cudnn': False} if core.is_compiled_with_rocm() else {}

8260 8261 8262
    helper.append_op(
        type='grid_sampler', inputs=ipts, outputs={'Output': out}, attrs=attrs
    )
8263 8264 8265
    return out


G
gmcather 已提交
8266
def log_loss(input, label, epsilon=1e-4, name=None):
8267
    r"""
8268

G
gmcather 已提交
8269 8270 8271 8272 8273 8274 8275
    **Negative Log Loss Layer**

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

    .. math::

8276 8277
        Out = -label * \log{(input + \epsilon)}
              - (1 - label) * \log{(1 - input + \epsilon)}
G
gmcather 已提交
8278 8279

    Args:
8280
        input (Tensor|list):  A 2-D tensor with shape [N x 1], where N is the
G
gmcather 已提交
8281
                                batch size. This input is a probability computed
Y
Yibing Liu 已提交
8282
                                by the previous operator. Data type float32.
8283
        label (Tensor|list):  The ground truth which is a 2-D tensor with
8284
                                shape [N x 1], where N is the batch size.
Y
Yibing Liu 已提交
8285 8286
                                Data type float32.
        epsilon (float, optional): A small number for numerical stability. Default 1e-4.
8287
        name(str|None): For detailed information, please refer to
Y
Yibing Liu 已提交
8288
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
G
gmcather 已提交
8289 8290

    Returns:
8291
        Tensor, which shape is [N x 1], data type is float32.
G
gmcather 已提交
8292 8293 8294 8295

    Examples:
        .. code-block:: python

8296 8297 8298 8299 8300 8301
          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 已提交
8302
    """
8303
    return paddle.nn.functional.log_loss(input, label, epsilon, name)
G
gmcather 已提交
8304 8305 8306


def add_position_encoding(input, alpha, beta, name=None):
8307
    r"""
8308

G
Guo Sheng 已提交
8309 8310
    This operator performs weighted sum of input feature at each position
    (position in the sequence) and the corresponding position encoding.
G
gmcather 已提交
8311

8312
    For more details of position encoding, please refer to `Attention Is All You
G
Guo Sheng 已提交
8313
    Need <http://arxiv.org/pdf/1706.03762.pdf>`_ .
G
gmcather 已提交
8314

G
Guo Sheng 已提交
8315
    The formula is as follows:
G
gmcather 已提交
8316 8317

    .. math::
H
haowang101779990 已提交
8318 8319 8320
        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 已提交
8321 8322

    Where:
G
Guo Sheng 已提交
8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336
      - :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.
8337 8338
        name(str, optional): For detailed information, please refer
            to :ref:`api_guide_Name`. Usually name is no need to set and
G
Guo Sheng 已提交
8339
            None by default.
G
gmcather 已提交
8340 8341

    Returns:
G
Guo Sheng 已提交
8342
        Variable: A Tensor or LoDTensor. It has the same shape, data type and lod as `input`.
G
gmcather 已提交
8343 8344 8345 8346

    Examples:
        .. code-block:: python

8347
          import paddle
8348

8349
          tensor = paddle.randn([16, 32, 64])
8350
          position_tensor = paddle.fluid.layers.add_position_encoding(
8351
                input=tensor, alpha=1.0, beta=1.0)
H
haowang101779990 已提交
8352

G
gmcather 已提交
8353
    """
J
Jiabin Yang 已提交
8354
    if _non_static_mode():
8355 8356 8357
        return _legacy_C_ops.add_position_encoding(
            input, "alpha", alpha, "beta", beta
        )
8358

G
gmcather 已提交
8359
    helper = LayerHelper('add_position_encoding', **locals())
8360 8361 8362
    check_variable_and_dtype(
        input, 'input', ['float32', 'float64'], "add_position_encoding"
    )
G
gmcather 已提交
8363 8364
    dtype = helper.input_dtype()

8365
    out = helper.create_variable_for_type_inference(dtype=dtype)
G
gmcather 已提交
8366

8367 8368 8369 8370 8371 8372
    helper.append_op(
        type="add_position_encoding",
        inputs={"X": input},
        outputs={"Out": out},
        attrs={"alpha": alpha, "beta": beta},
    )
G
gmcather 已提交
8373
    return out
Q
Qiao Longfei 已提交
8374 8375


8376 8377 8378
def bilinear_tensor_product(
    x, y, size, act=None, name=None, param_attr=None, bias_attr=None
):
8379
    r"""
8380 8381
    :api_attr: Static Graph

Y
Yibing Liu 已提交
8382
    **Bilinear Tensor Product Layer**
Q
Qiao Longfei 已提交
8383

Q
Qiao Longfei 已提交
8384
    This layer performs bilinear tensor product on two inputs.
Q
Qiao Longfei 已提交
8385 8386 8387
    For example:

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

Q
Qiao Longfei 已提交
8390
    In this formula:
8391 8392
      - :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 已提交
8393
      - :math:`W_{i}`: the i-th learned weight, shape is [M, N].
H
haowang101779990 已提交
8394
      - :math:`out_{i}`: the i-th element of out, shape is [batch_size, size].
Q
Qiao Longfei 已提交
8395 8396 8397
      - :math:`y^\mathrm{T}`: the transpose of :math:`y_{2}`.

    Args:
8398
        x (Variable): 2-D input tensor with shape [batch_size, M]. Data type
Y
Yibing Liu 已提交
8399
            is float32 or float64.
8400
        y (Variable): 2-D input tensor with shape [batch_size, N]. Data type
Y
Yibing Liu 已提交
8401
            should be same as **x**.
Q
Qiao Longfei 已提交
8402
        size (int): The dimension of this layer.
Y
Yibing Liu 已提交
8403
        act (str|None): Activation to be applied to the output of this layer. Default None.
8404
        name(str|None): For detailed information, please refer to
Y
Yibing Liu 已提交
8405
            :ref:`api_guide_Name` . Usually name is no need to set and None by default.
8406 8407
        param_attr (ParamAttr|None): To specify the weight parameter attribute.
            Default: None, which means the default weight parameter property is
Y
Yibing Liu 已提交
8408
            used. See usage for details in :ref:`api_fluid_ParamAttr` .
8409 8410
        bias_attr (ParamAttr|None): To specify the bias parameter attribute.
            Default: None, which means the default bias parameter property is
Y
Yibing Liu 已提交
8411
            used. See usage for details in :ref:`api_fluid_ParamAttr` .
Q
Qiao Longfei 已提交
8412
    Returns:
Y
Yibing Liu 已提交
8413
        Variable: A 2-D Tensor of shape [batch_size, size]. Data type is the same as input **x**.
Q
Qiao Longfei 已提交
8414 8415 8416 8417

    Examples:
        .. code-block:: python

8418 8419 8420 8421 8422
            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 已提交
8423 8424
    """
    helper = LayerHelper('bilinear_tensor_product', **locals())
Q
Qiao Longfei 已提交
8425
    dtype = helper.input_dtype('x')
Q
Qiao Longfei 已提交
8426 8427 8428

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

8429 8430 8431
    w = helper.create_parameter(
        attr=helper.param_attr, shape=param_shape, dtype=dtype, is_bias=False
    )
8432
    out = helper.create_variable_for_type_inference(dtype=dtype)
Q
Qiao Longfei 已提交
8433 8434 8435 8436

    inputs = {"X": x, "Y": y, "Weight": w}
    if helper.bias_attr:
        bias_size = [1, size]
8437 8438 8439
        bias = helper.create_parameter(
            attr=helper.bias_attr, shape=bias_size, dtype=dtype, is_bias=True
        )
Q
Qiao Longfei 已提交
8440
        inputs["Bias"] = bias
8441 8442 8443
    helper.append_op(
        type="bilinear_tensor_product", inputs=inputs, outputs={"Out": out}
    )
Q
Qiao Longfei 已提交
8444 8445 8446

    # add activation
    return helper.append_activation(out)
C
chengduo 已提交
8447 8448 8449 8450 8451


@templatedoc()
def get_tensor_from_selected_rows(x, name=None):
    """
8452 8453 8454 8455 8456 8457 8458 8459 8460
    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]]

8461
        Output is LoDTensor:
8462 8463 8464 8465 8466 8467
           out.shape = [5, 2]
           out.data = [[1, 1],
                       [2, 2],
                       [2, 2],
                       [3, 3],
                       [6, 6]]
C
chengduo 已提交
8468 8469

    Args:
8470 8471 8472
        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 已提交
8473 8474

    Returns:
8475
        Variable: LoDTensor transformed from SelectedRows. The data type is same with input.
B
bdzhuxiaoning 已提交
8476 8477 8478

    Examples:
        .. code-block:: python
8479

B
bdzhuxiaoning 已提交
8480 8481 8482 8483
            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 已提交
8484 8485
    """

8486 8487 8488 8489 8490
    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 已提交
8491 8492
    helper = LayerHelper('get_tensor_from_selected_rows', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
8493 8494 8495 8496 8497 8498
    helper.append_op(
        type='get_tensor_from_selected_rows',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={},
    )
C
chengduo 已提交
8499
    return out
8500 8501


8502
@templatedoc()
8503
def temporal_shift(x, seg_num, shift_ratio=0.25, name=None, data_format="NCHW"):
8504
    """
8505

8506
    **Temporal Shift Operator**
8507

8508
    ${comment}
8509 8510

    Args:
8511
        x(Tensor): ${x_comment}
8512
        seg_num(int): ${seg_num_comment}
D
dengkaipeng 已提交
8513
        shift_ratio(float): ${shift_ratio_comment}
K
Kaipeng Deng 已提交
8514 8515 8516
        name(str, optional): For detailed information, please refer
                             to :ref:`api_guide_Name`. Usually name is no need to set and
                             None by default.
8517 8518
        data_format(str, optional): Data format that specifies the layout of input.
            It can be "NCHW" or "NHWC". Default: "NCHW".
8519 8520

    Returns:
8521
        out(Tensor): The temporal shifting result is a tensor with the
K
Kaipeng Deng 已提交
8522
        same shape and same data type as the input.
8523 8524 8525 8526 8527 8528 8529

    Raises:
        TypeError: seg_num must be int type.

    Examples:
        .. code-block:: python

8530 8531 8532 8533
            import paddle
            import paddle.nn.functional as F

            input = paddle.randn([6, 4, 2, 2])
8534
            out = F.temporal_shift(x=input, seg_num=2, shift_ratio=0.2)
8535
    """
8536 8537 8538
    return paddle.nn.functional.temporal_shift(
        x, seg_num, shift_ratio, name, data_format
    )
8539 8540


8541
class PyFuncRegistry:
S
sneaxiy 已提交
8542 8543 8544
    _register_funcs = []

    def __init__(self, func):
S
sneaxiy 已提交
8545
        if func is None or not callable(func):
S
sneaxiy 已提交
8546 8547 8548
            raise TypeError('func must be a Python function')

        self._func = func
M
minqiyang 已提交
8549
        # find named args using reflection
8550
        args = inspect.getfullargspec(self._func)
S
sneaxiy 已提交
8551 8552 8553 8554 8555 8556
        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 已提交
8557 8558 8559
        '''
        Why record self here?

M
minqiyang 已提交
8560 8561
        1. For debug usage. Users can call
           :code:`py_func.registered_func(idx)` method
S
sneaxiy 已提交
8562
           to find the registered function corresponding
M
minqiyang 已提交
8563
           to :code:`idx`.
S
sneaxiy 已提交
8564

M
minqiyang 已提交
8565 8566
        2. For increasing reference count of self.
           It seems that to release Python object
S
sneaxiy 已提交
8567
           whose reference count is 1 would cause
M
minqiyang 已提交
8568
           segmentation fault error in C++ side.
S
sneaxiy 已提交
8569 8570
           May be lack of Python GC in C++ side?
        '''
S
sneaxiy 已提交
8571
        PyFuncRegistry._register_funcs.append(self)
S
sneaxiy 已提交
8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583 8584 8585

    @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 已提交
8586 8587 8588 8589 8590 8591 8592 8593 8594
        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 已提交
8595

S
sneaxiy 已提交
8596
        if not isinstance(func_ret, (list, tuple)):
8597
            func_ret = (func_ret,)
S
sneaxiy 已提交
8598 8599

        ret = []
S
sneaxiy 已提交
8600 8601 8602
        for each_ret in func_ret:
            if each_ret is None or isinstance(each_ret, core.LoDTensor):
                ret.append(each_ret)
S
sneaxiy 已提交
8603 8604
                continue

S
sneaxiy 已提交
8605 8606
            if not isinstance(each_ret, np.ndarray):
                each_ret = np.array(each_ret)
S
sneaxiy 已提交
8607

S
sneaxiy 已提交
8608 8609 8610
            tensor = core.LoDTensor()
            tensor.set(each_ret, core.CPUPlace())
            ret.append(tensor)
S
sneaxiy 已提交
8611

S
sneaxiy 已提交
8612
        return tuple(ret)
S
sneaxiy 已提交
8613 8614


8615
@static_only
S
sneaxiy 已提交
8616 8617 8618
@templatedoc()
def py_func(func, x, out, backward_func=None, skip_vars_in_backward_input=None):
    """
8619 8620
    :api_attr: Static Graph

8621 8622
    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
8623 8624
    other easily. So you can use Python and numpy API to register a python OP.

8625 8626
    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
8627
    call ``backward_func`` at backward runtime(if ``backward_func`` is not  None).
8628 8629
    ``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.
8630

8631
    The input of the backward function ``backward_func`` is ``x``, ``out`` and
8632 8633 8634
    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``.
8635

8636 8637
    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
8638 8639 8640 8641 8642 8643 8644
    ``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
8645 8646
            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
8647
            actively convert Tensor into a numpy array, so that we can use Python and
8648
            numpy API arbitrarily. If not, some operations of numpy may not be compatible.
8649 8650 8651 8652 8653 8654 8655
        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.
8656 8657 8658
        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
8659
            ``x`` when the network is at backward runtime.
8660 8661
        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].
8662
            It must belong to either ``x`` or ``out``. The default  value is None, which means
8663 8664
            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
8665
            useful when ``backward_func`` is not None.
8666 8667

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

    Examples:
8671
        .. code-block:: python
8672

8673
            # example 1:
8674
            import paddle
8675
            import numpy as np
8676

8677 8678 8679
            paddle.enable_static()

            # Creates a forward function, Tensor can be input directly without
8680
            # being converted into numpy array.
8681 8682 8683
            def tanh(x):
                return np.tanh(x)

8684
            # Skip x in backward function and return the gradient of x
8685
            # Tensor must be actively converted to numpy array, otherwise,
8686
            # operations such as +/- can't be used.
8687 8688
            def tanh_grad(y, dy):
                return np.array(dy) * (1 - np.square(np.array(y)))
8689

8690
            # Creates a forward function for debugging running networks(print value)
8691 8692
            def debug_func(x):
                print(x)
8693

8694
            def create_tmp_var(name, dtype, shape):
8695
                return paddle.static.default_main_program().current_block().create_var(
8696
                    name=name, dtype=dtype, shape=shape)
8697 8698 8699

            def simple_net(img, label):
                hidden = img
8700
                for idx in range(4):
8701
                    hidden = paddle.static.nn.fc(hidden, size=200)
8702 8703 8704
                    new_hidden = create_tmp_var(name='hidden_{}'.format(idx),
                        dtype=hidden.dtype, shape=hidden.shape)

8705
                    # User-defined forward and backward
8706
                    hidden = paddle.static.py_func(func=tanh, x=hidden,
8707 8708 8709
                        out=new_hidden, backward_func=tanh_grad,
                        skip_vars_in_backward_input=hidden)

8710
                    # User-defined debug functions that print out the input Tensor
8711
                    paddle.static.py_func(func=debug_func, x=hidden, out=None)
8712

8713
                prediction = paddle.static.nn.fc(hidden, size=10, activation='softmax')
8714 8715 8716 8717
                ce_loss = paddle.nn.loss.CrossEntropyLoss()
                return ce_loss(prediction, label)

            x = paddle.static.data(name='x', shape=[1,4], dtype='float32')
8718
            y = paddle.static.data(name='y', shape=[1], dtype='int64')
8719 8720 8721 8722 8723
            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')
8724
            input2 = np.random.randint(1, 10, size=[1], dtype='int64')
8725 8726 8727 8728 8729 8730
            out = exe.run(paddle.static.default_main_program(),
                          feed={'x':input1, 'y':input2},
                          fetch_list=[res.name])
            print(out)

        .. code-block:: python
8731

8732
            # example 2:
8733
            # This example shows how to turn Tensor into numpy array and
8734
            # use numpy API to register an Python OP
8735
            import paddle
8736 8737
            import numpy as np

8738 8739
            paddle.enable_static()

8740
            def element_wise_add(x, y):
8741
                # Tensor must be actively converted to numpy array, otherwise,
8742
                # numpy.shape can't be used.
8743
                x = np.array(x)
8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 8756
                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):
8757
                return paddle.static.default_main_program().current_block().create_var(
8758 8759 8760
                            name=name, dtype=dtype, shape=shape)

            def py_func_demo():
8761 8762
                start_program = paddle.static.default_startup_program()
                main_program = paddle.static.default_main_program()
8763 8764

                # Input of the forward function
8765 8766
                x = paddle.static.data(name='x', shape=[2,3], dtype='int32')
                y = paddle.static.data(name='y', shape=[2,3], dtype='int32')
8767

8768 8769 8770 8771
                # 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]
8772
                paddle.static.py_func(func=element_wise_add, x=[x,y], out=output)
8773

8774
                exe=paddle.static.Executor(paddle.CPUPlace())
8775 8776 8777 8778 8779
                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')
8780
                out = exe.run(main_program,
8781 8782 8783 8784 8785 8786 8787 8788 8789
                            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 已提交
8790
    """
S
sneaxiy 已提交
8791
    helper = LayerHelper('py_func', **locals())
8792
    check_type(x, 'X', (list, tuple, Variable, type(None)), 'py_func')
S
sneaxiy 已提交
8793 8794 8795
    if x is None:
        x = []
    elif isinstance(x, Variable):
S
sneaxiy 已提交
8796
        x = [x]
8797 8798 8799
    elif isinstance(x, tuple):
        x = list(x)
    elif not isinstance(x, (list, tuple, Variable)):
S
sneaxiy 已提交
8800
        raise TypeError('Input must be Variable/list(Variable)/tuple(Variable)')
8801
    check_type(out, 'Out', (list, tuple, Variable, type(None)), 'py_func')
S
sneaxiy 已提交
8802 8803 8804
    if out is None:
        out_list = []
    elif isinstance(out, Variable):
S
sneaxiy 已提交
8805
        out_list = [out]
8806 8807
    elif isinstance(out, tuple):
        out_list = list(out)
8808 8809 8810
    elif isinstance(out, list):
        out_list = out
    else:
S
sneaxiy 已提交
8811
        raise TypeError(
8812 8813
            'Output must be Variable/list(Variable)/tuple(Variable)'
        )
S
sneaxiy 已提交
8814

S
sneaxiy 已提交
8815
    fwd_func_id = PyFuncRegistry(func).id
8816 8817 8818
    bwd_func_id = (
        PyFuncRegistry(backward_func).id if backward_func is not None else -1
    )
S
sneaxiy 已提交
8819 8820

    for each_out in out_list:
S
sneaxiy 已提交
8821 8822
        if len(each_out.shape) == 0:
            raise ValueError(
S
sneaxiy 已提交
8823 8824
                'Output shapes of py_func op should be provided by users manually'
            )
S
sneaxiy 已提交
8825

S
sneaxiy 已提交
8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837
    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(
8838 8839 8840 8841
                    'Variable {} is not found in forward inputs and outputs'.format(
                        v.name
                    )
                )
S
sneaxiy 已提交
8842
            backward_skip_vars.add(v.name)
S
sneaxiy 已提交
8843

8844 8845 8846 8847 8848 8849 8850 8851 8852 8853
    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 已提交
8854
    return out
S
sneaxiy 已提交
8855 8856 8857


# For debug usage
S
sneaxiy 已提交
8858 8859 8860 8861
py_func.registered_func = PyFuncRegistry.registered_func
py_func.registered_func_num = PyFuncRegistry.registered_func_num


R
ruri 已提交
8862 8863 8864
def pixel_shuffle(x, upscale_factor):
    """

R
ruri 已提交
8865
    This op rearranges elements in a tensor of shape [N, C, H, W]
R
ruri 已提交
8866 8867 8868
    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.
8869
    Please refer to the paper: `Real-Time Single Image and Video Super-Resolution
R
ruri 已提交
8870 8871 8872
    Using an Efficient Sub-Pixel Convolutional Neural Network <https://arxiv.org/abs/1609.05158v2>`_ .
    by Shi et. al (2016) for more details.

R
ruri 已提交
8873
    Parameters:
R
ruri 已提交
8874

R
ruri 已提交
8875 8876
        x(Variable): 4-D tensor, the data type should be float32 or float64.
        upscale_factor(int): factor to increase spatial resolution.
R
ruri 已提交
8877 8878

    Returns:
8879
        Out(Variable): Reshaped tensor according to the new dimension.
R
ruri 已提交
8880 8881 8882 8883 8884 8885 8886

    Raises:
        ValueError: If the square of upscale_factor cannot divide the channels of input.

    Examples:
        .. code-block:: python

8887 8888 8889 8890 8891 8892 8893 8894
            # 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())
8895

8896 8897
            input_data = np.random.rand(2,9,4,4).astype("float32")
            output_data = exe.run(fluid.default_main_program(),
R
ruri 已提交
8898 8899 8900
                feed={"input":input_data},
                fetch_list=[output],
                return_numpy=True)
8901

8902 8903
            # print(output.shape)
            # (2L, 1L, 12L, 12L)
R
ruri 已提交
8904 8905 8906

    """

R
ruri 已提交
8907
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'pixel_shuffle')
R
ruri 已提交
8908 8909 8910 8911 8912 8913 8914
    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")

8915 8916 8917 8918 8919 8920
    helper.append_op(
        type="pixel_shuffle",
        inputs={"X": x},
        outputs={"Out": out},
        attrs={"upscale_factor": upscale_factor},
    )
R
ruri 已提交
8921 8922 8923
    return out


8924 8925 8926 8927 8928
def fsp_matrix(x, y):
    """

    **FSP matrix op**

8929
    This op is used to calculate the flow of solution procedure (FSP) matrix of two 4-D Tensor feature maps.
8930 8931 8932 8933 8934 8935 8936 8937 8938 8939 8940
    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:

8941 8942 8943
        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].
8944
                      The y_channel can be different with the x_channel of Input(X)
8945 8946
                      while the other dimensions must be the same with Input(X)'s. A Tensor with
                      type float32, float64.
8947 8948 8949 8950

    Returns:

        fsp matrix (Variable): The output of FSP op with shape [batch_size, x_channel, y_channel].
8951 8952
        The x_channel is the channel of x and the y_channel is the channel of y. A Tensor with
        type float32, float64.
8953 8954 8955 8956 8957

    Examples:

        .. code-block:: python

B
Bai Yifan 已提交
8958
            import paddle.fluid as fluid
B
Bai Yifan 已提交
8959
            data = fluid.data(name='data', shape=[None, 3, 32, 32])
B
Bai Yifan 已提交
8960 8961 8962 8963
            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)
8964 8965 8966
            loss = fluid.layers.fsp_matrix(feature_map_0, feature_map_1)

    """
8967 8968
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'fsp_matrix')
    check_variable_and_dtype(y, 'y', ['float32', 'float64'], 'fsp_matrix')
8969
    helper = LayerHelper('fsp_matrix', **locals())
8970 8971 8972
    out = helper.create_variable_for_type_inference(
        dtype=helper.input_dtype(input_param_name='x')
    )
8973 8974
    helper.append_op(type='fsp', inputs={'X': x, 'Y': y}, outputs={'Out': out})
    return out
H
heqiaozhi 已提交
8975 8976 8977


def continuous_value_model(input, cvm, use_cvm=True):
8978
    r"""
H
fix doc  
heqiaozhi 已提交
8979

H
heqiaozhi 已提交
8980
    **continuous_value_model layers**
H
fix doc  
heqiaozhi 已提交
8981

Z
zhoushiyu 已提交
8982
    Now, this OP is used in CTR project to remove or dispose show and click value in :attr:`input`.
H
fix doc  
heqiaozhi 已提交
8983

Z
zhoushiyu 已提交
8984 8985
    :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 已提交
8986
    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 已提交
8987 8988
    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 已提交
8989

Z
zhoushiyu 已提交
8990 8991 8992 8993 8994 8995 8996
    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 已提交
8997

H
heqiaozhi 已提交
8998
    Returns:
H
fix doc  
heqiaozhi 已提交
8999

Z
zhoushiyu 已提交
9000 9001
        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 已提交
9002

H
heqiaozhi 已提交
9003
    Examples:
H
fix doc  
heqiaozhi 已提交
9004

H
heqiaozhi 已提交
9005
        .. code-block:: python
H
fix doc  
heqiaozhi 已提交
9006

9007
          import paddle.fluid as fluid
Z
zhoushiyu 已提交
9008 9009
          input = fluid.data(name="input", shape=[64, 1], dtype="int64")
          label = fluid.data(name="label", shape=[64, 1], dtype="int64")
H
heqiaozhi 已提交
9010 9011 9012 9013 9014 9015 9016 9017
          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 已提交
9018

H
heqiaozhi 已提交
9019 9020 9021
    """
    helper = LayerHelper('cvm', **locals())
    out = helper.create_variable(dtype=input.dtype)
9022 9023 9024 9025 9026 9027 9028 9029 9030
    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 已提交
9031
    return out
Z
zhoukunsheng 已提交
9032 9033 9034 9035 9036 9037 9038


def where(condition):
    """
    Return an int64 tensor with rank 2, specifying the coordinate of true element in `condition`.

    Args:
9039
        condition(Variable): A bool tensor with rank at least 1, the data type is bool.
Z
zhoukunsheng 已提交
9040 9041

    Returns:
9042
        Variable, the output data type is int64. : The tensor variable storing a 2-D tensor, which involves all coordinate.
Z
zhoukunsheng 已提交
9043 9044 9045 9046

    Examples:
        .. code-block:: python

9047
             import paddle.fluid as fluid
9048 9049 9050
             import paddle.fluid.layers as layers
             import numpy as np

Z
zhoukunsheng 已提交
9051
             # condition is a tensor [True, False, True]
9052 9053 9054
             condition = layers.assign(np.array([1, 0, 1], dtype='int32'))
             condition = layers.cast(condition, 'bool')
             out = layers.where(condition) # [[0], [2]]
Z
zhoukunsheng 已提交
9055 9056

             # condition is a tensor [[True, False], [False, True]]
9057 9058 9059
             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 已提交
9060 9061

             # condition is a tensor [False, False, False]
9062 9063 9064 9065
             condition = layers.assign(np.array([0, 0, 0], dtype='int32'))
             condition = layers.cast(condition, 'bool')
             out = layers.where(condition) # [[]]

Z
zhoukunsheng 已提交
9066
    """
H
hong 已提交
9067 9068

    if in_dygraph_mode():
9069
        return _C_ops.nonzero(condition)
9070 9071
    if _in_legacy_dygraph():
        return _legacy_C_ops.where_index(condition)
9072

W
wanghuancoder 已提交
9073 9074
    helper = LayerHelper("where_index", **locals())

Z
zhoukunsheng 已提交
9075
    out = helper.create_variable_for_type_inference(
9076 9077 9078 9079 9080 9081 9082 9083
        dtype=core.VarDesc.VarType.INT64
    )

    helper.append_op(
        type='where_index',
        inputs={'Condition': condition},
        outputs={'Out': [out]},
    )
Z
zhoukunsheng 已提交
9084
    return out
Z
zhoukunsheng 已提交
9085 9086


W
WangXi 已提交
9087
@deprecated(since="2.0.0", update_to="paddle.sign")
Z
zhoukunsheng 已提交
9088
def sign(x):
9089
    r"""
9090
    This OP returns sign of every element in `x`: 1 for positive, -1 for negative and 0 for zero.
Z
zhoukunsheng 已提交
9091 9092

    Args:
9093 9094
        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 已提交
9095 9096

    Returns:
9097
        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 已提交
9098 9099 9100 9101

    Examples:
        .. code-block:: python

9102 9103 9104
          import paddle.fluid as fluid
          import numpy as np

9105
          # [1.0, 0.0, -1.0]
9106
          data = fluid.layers.sign(np.array([3.0, 0.0, -2.0], dtype='float32'))
Z
zhoukunsheng 已提交
9107 9108 9109
    """

    helper = LayerHelper("sign", **locals())
9110 9111 9112 9113
    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 已提交
9114 9115 9116 9117 9118
    out = helper.create_variable_for_type_inference(dtype=x.dtype)

    helper.append_op(type='sign', inputs={'X': [x]}, outputs={'Out': [out]})

    return out
9119 9120


Z
zhoukunsheng 已提交
9121
def unique(x, dtype='int32'):
9122
    r"""
Z
zhoukunsheng 已提交
9123 9124 9125
    Return a unique tensor for `x` and an index tensor pointing to this unique tensor.

    Args:
Z
Zhang Ting 已提交
9126 9127
        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 已提交
9128 9129 9130 9131 9132 9133 9134 9135 9136 9137

    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 已提交
9138
             x = fluid.layers.assign(np.array([2, 3, 3, 1, 5, 3], dtype='int32'))
Z
zhoukunsheng 已提交
9139 9140 9141
             out, index = fluid.layers.unique(x) # out is [2, 3, 1, 5]; index is [0, 1, 1, 2, 3, 1]
    """

9142 9143 9144
    check_variable_and_dtype(
        x, "x", ['float32', 'float64', 'int32', 'int64'], "unique"
    )
Z
zhoukunsheng 已提交
9145 9146 9147 9148 9149 9150
    helper = LayerHelper("unique", **locals())

    out = helper.create_variable_for_type_inference(dtype=x.dtype)

    index = helper.create_variable_for_type_inference(dtype)

9151 9152 9153 9154 9155 9156
    helper.append_op(
        type='unique',
        inputs={'X': x},
        attrs={'dtype': convert_np_dtype_to_dtype_(dtype)},
        outputs={'Out': [out], 'Index': [index]},
    )
Z
zhoukunsheng 已提交
9157 9158 9159 9160

    return out, index


9161
def unique_with_counts(x, dtype='int32'):
9162
    r"""
T
tianshuo78520a 已提交
9163
    This OP return a unique tensor for `x` , and count tensor that the count of unique result in raw input, \
9164
    and an index tensor pointing to this unique tensor.
9165

9166
    **NOTICE**: This op support the variable type of Tensor only.
9167 9168

    Args:
9169
        x(Variable): A 1-D input tensor with input shape of :math:`[N]` , the input data type is float32, float64, int32, int64.
9170
        dtype(np.dtype|core.VarDesc.VarType|str): The type of count and index tensor, it could be int32, int64. Default value is int32.
9171

9172
    Returns:
9173 9174 9175
        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 已提交
9176
        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\
9177
        the :attr:`x`, the data shape is :math:`[K]`, the data shape is the same as output :attr:`out`.
9178 9179 9180 9181 9182 9183 9184 9185 9186

    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]
9187
            # x.shape=(6,) out.shape=(4,), index.shape=(6,), count.shape=(4,)
9188
    """
9189 9190 9191
    check_variable_and_dtype(
        x, "x", ['float32', 'float64', 'int32', 'int64'], "unique_with_counts"
    )
9192 9193
    if not (dtype == 'int32' or dtype == 'int64'):
        raise TypeError(
9194 9195
            "Op unique_with_counts, index dtype must be int32 or int64"
        )
9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209

    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)

9210 9211 9212 9213 9214 9215
    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]},
    )
9216 9217 9218 9219

    return out, index, count


9220
def unfold(x, kernel_sizes, strides=1, paddings=0, dilations=1, name=None):
9221
    r"""
9222

S
SunGaofeng 已提交
9223
    This op returns a col buffer of sliding local blocks of input x, also known
9224
    as im2col for batched 2D image tensors. For each block under the convolution filter,
T
tianshuo78520a 已提交
9225
    all element will be rearranged as a column. While the convolution filter sliding over
9226 9227
    the input feature map, a series of such columns will be formed.

S
SunGaofeng 已提交
9228
    For each input :math:`x` with shape [N, C, H, W], the output shape [N, Cout, Lout]
9229 9230 9231 9232
    can be calculated as following.

    .. math::

9233
        dkernel[0] &= dilations[0] \times (kernel\_sizes[0] - 1) + 1
9234

9235
        dkernel[1] &= dilations[1] \times (kernel\_sizes[1] - 1) + 1
9236

9237
        hout &= \frac{H + paddings[0] + paddings[2] - dkernel[0]}{strides[0]} + 1
9238

9239
        wout &= \frac{W + paddings[1] + paddings[3] - dkernel[1]}{strides[1]} + 1
9240

9241
        Cout &= C \times kernel\_sizes[0] \times kernel\_sizes[1]
9242

9243
        Lout &= hout \times wout
9244 9245


S
SunGaofeng 已提交
9246
    Parameters:
9247
        x(Tensor):              4-D Tensor, input tensor of format [N, C, H, W],
S
SunGaofeng 已提交
9248
                                  data type can be float32 or float64
9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260
        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 已提交
9261
        dilations(int|list):      the dilations of convolution kernel, should be
T
tianshuo78520a 已提交
9262
                                  [dilation_h, dilation_w], or an integer dilation treated as
9263
                                  [dilation, dilation]. For default, it will be [1, 1].
9264 9265
        name(str, optional): The default value is None.
                             Normally there is no need for user to set this property.
S
SunGaofeng 已提交
9266
                             For more information, please refer to :ref:`api_guide_Name`
9267

9268

9269
    Returns:
9270
        The tensor corresponding to the sliding local blocks.
9271 9272 9273
        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 已提交
9274 9275 9276
        The data type of output is the same as the input :math:`x`

    Return Type:
9277
        Tensor
9278 9279 9280 9281 9282

    Examples:

        .. code-block:: python

9283 9284 9285 9286 9287
            import paddle
            import paddle.nn.functional as F

            x = paddle.randn((100,3,224,224))
            y = F.unfold(x, [3, 3], 1, 1, 1)
9288 9289
    """

9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302 9303 9304 9305 9306 9307 9308 9309
    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,
):
9310
    r"""
9311

9312
    Deformable ROI Pooling Layer
9313

9314
    Performs deformable region-of-interest pooling on inputs. As described
9315
    in `Deformable Convolutional Networks <https://arxiv.org/abs/1703.06211>`_, it will get offset for each bin after
9316
    roi pooling so that pooling at correct region. Batch_size will change to the number of region bounding boxes after deformable_roi_pooling.
9317

9318
    The operation has three steps:
9319

9320
    1. Dividing each region proposal into equal-sized sections with the pooled_width and pooled_height.
9321

9322 9323
    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.
9324

9325
    3. Sample several points in each bin to get average values as output.
9326 9327


9328 9329 9330 9331 9332 9333 9334 9335 9336
    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.
9337 9338 9339
        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.
9340 9341 9342 9343
        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.
9344
        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
9345
                          is k1 * k2 * (C + 1), which k1 and k2 are group width and height and C+1 is number of output
T
tianshuo78520a 已提交
9346
                          channels.) eg.(4, 6), which 4 is height of group and 6 is width of group. Default: [1, 1].
9347 9348 9349 9350 9351 9352 9353
        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 已提交
9354
                                   If value is True, input dimension should be output dimension * pooled_height * pooled_width. Default: False.
9355 9356 9357 9358
        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 已提交
9359 9360 9361 9362

    Examples:
      .. code-block:: python

9363 9364
        # position_sensitive=True
        import paddle.fluid as fluid
C
chengjuntao 已提交
9365
        input = fluid.data(name="input",
9366 9367
                           shape=[2, 192, 64, 64],
                           dtype='float32')
C
chengjuntao 已提交
9368 9369
        rois = fluid.data(name="rois",
                          shape=[-1, 4],
9370
                          dtype='float32',
C
chengjuntao 已提交
9371 9372
                          lod_level=1)
        trans = fluid.data(name="trans",
9373 9374 9375 9376 9377
                           shape=[2, 384, 64, 64],
                           dtype='float32')
        x = fluid.layers.deformable_roi_pooling(input=input,
                                                rois=rois,
                                                trans=trans,
C
chengjuntao 已提交
9378
                                                no_trans=False,
9379
                                                spatial_scale=1.0,
C
chengjuntao 已提交
9380 9381 9382 9383
                                                group_size=(1, 1),
                                                pooled_height=8,
                                                pooled_width=8,
                                                part_size=(8, 8),
9384
                                                sample_per_part=4,
C
chengjuntao 已提交
9385 9386
                                                trans_std=0.1,
                                                position_sensitive=True)
9387

9388
        # position_sensitive=False
9389
        import paddle.fluid as fluid
C
chengjuntao 已提交
9390
        input = fluid.data(name="input",
9391 9392
                           shape=[2, 192, 64, 64],
                           dtype='float32')
C
chengjuntao 已提交
9393 9394
        rois = fluid.data(name="rois",
                          shape=[-1, 4],
9395
                          dtype='float32',
C
chengjuntao 已提交
9396 9397
                          lod_level=1)
        trans = fluid.data(name="trans",
9398 9399 9400 9401 9402
                           shape=[2, 384, 64, 64],
                           dtype='float32')
        x = fluid.layers.deformable_roi_pooling(input=input,
                                                rois=rois,
                                                trans=trans,
C
chengjuntao 已提交
9403
                                                no_trans=False,
9404
                                                spatial_scale=1.0,
C
chengjuntao 已提交
9405 9406 9407 9408
                                                group_size=(1, 1),
                                                pooled_height=8,
                                                pooled_width=8,
                                                part_size=(8, 8),
9409
                                                sample_per_part=4,
C
chengjuntao 已提交
9410 9411
                                                trans_std=0.1,
                                                position_sensitive=False)
C
cjt222 已提交
9412 9413
    """

9414 9415 9416 9417 9418 9419 9420 9421 9422 9423 9424 9425
    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'
    )
9426
    if part_size is not None:
9427 9428 9429
        check_type(
            part_size, 'part_size', (list, tuple), 'deformable_roi_pooling'
        )
9430

C
cjt222 已提交
9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446
    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')
9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462
    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 已提交
9463
    return output
9464 9465


9466
@deprecated(since="2.0.0", update_to="paddle.shard_index")
9467 9468
def shard_index(input, index_num, nshards, shard_id, ignore_value=-1):
    """
L
lilong12 已提交
9469 9470 9471 9472 9473 9474 9475 9476 9477
    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).
9478 9479
    ::

9480
        shard_size = (index_num + nshards - 1) // nshards
9481

L
lilong12 已提交
9482 9483 9484
    For each value `v` in `input`, we reset it to a new value according to the
    following formula:
    ::
9485

L
lilong12 已提交
9486 9487 9488 9489
        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`.
9490 9491

    Args:
L
lilong12 已提交
9492 9493
        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`.
9494 9495 9496
        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.
9497 9498

    Returns:
L
lilong12 已提交
9499
        Tensor.
9500 9501 9502 9503

    Examples:
        .. code-block:: python

9504 9505 9506 9507 9508 9509 9510 9511
            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]]
9512
    """
H
hong 已提交
9513
    if in_dygraph_mode():
9514 9515 9516
        return _C_ops.shard_index(
            input, index_num, nshards, shard_id, ignore_value
        )
H
hong 已提交
9517

B
Baibaifan 已提交
9518
    check_variable_and_dtype(input, 'input', ['int64', 'int32'], 'shard_index')
9519 9520 9521
    op_type = 'shard_index'
    helper = LayerHelper(op_type, **locals())
    if shard_id < 0 or shard_id >= nshards:
9522 9523 9524
        raise ValueError(
            'The shard_id(%d) should be in [0, %d)' % (shard_id, nshards)
        )
9525 9526

    out = helper.create_variable_for_type_inference(dtype=input.dtype)
9527 9528 9529 9530 9531 9532 9533 9534 9535 9536 9537 9538
    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,
    )
9539
    return out
H
huangjun12 已提交
9540 9541 9542 9543


@templatedoc()
def hard_swish(x, threshold=6.0, scale=6.0, offset=3.0, name=None):
9544
    r"""
9545 9546 9547
    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 已提交
9548

9549
    The formula is as follows:
H
huangjun12 已提交
9550

9551
    .. math::
H
huangjun12 已提交
9552

9553
        out = \\frac{x * (min(max(0, x+offset), threshold))}{scale}
H
huangjun12 已提交
9554

9555 9556 9557 9558 9559 9560 9561 9562 9563
    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
9564 9565
        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`

9566 9567
    Returns:
        Variable: The output tensor with the same shape and data type as input.
9568 9569


9570
    Examples:
9571

9572
    .. code-block:: python
9573

9574
        import paddle.fluid as fluid
9575
        import paddle
9576
        import numpy as np
9577
        paddle.enable_static()
9578

9579
        DATATYPE='float32'
9580

9581
        x_data = np.array([i for i in range(1,5)]).reshape([1,1,4]).astype(DATATYPE)
9582

9583 9584
        x = fluid.data(name="x", shape=[None,1,4], dtype=DATATYPE)
        y = fluid.layers.hard_swish(x)
9585

9586 9587 9588 9589 9590
        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 已提交
9591
    """
J
Jiabin Yang 已提交
9592
    if _non_static_mode():
9593 9594 9595
        return _legacy_C_ops.hard_swish(
            x, 'threshold', threshold, 'scale', scale, 'offset', offset
        )
9596

9597 9598 9599
    check_variable_and_dtype(
        x, 'x', ['float16', 'float32', 'float64'], 'hard_swish'
    )
9600

H
huangjun12 已提交
9601 9602
    helper = LayerHelper('hard_swish', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
9603 9604 9605 9606 9607 9608
    helper.append_op(
        type='hard_swish',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'threshold': threshold, 'scale': scale, 'offset': offset},
    )
H
huangjun12 已提交
9609
    return out
R
ruri 已提交
9610 9611


K
Kaipeng Deng 已提交
9612 9613
@templatedoc()
def mish(x, threshold=20, name=None):
9614
    r"""
K
Kaipeng Deng 已提交
9615 9616 9617 9618 9619 9620 9621 9622 9623 9624 9625 9626 9627 9628 9629 9630 9631 9632 9633 9634 9635 9636 9637 9638 9639 9640 9641 9642 9643 9644 9645 9646 9647 9648 9649 9650 9651 9652 9653 9654 9655 9656 9657 9658 9659 9660 9661 9662 9663 9664 9665 9666 9667 9668 9669 9670 9671
    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.]]
    """
9672
    if in_dygraph_mode():
9673
        return _C_ops.mish(x, threshold)
9674
    if _in_legacy_dygraph():
9675
        return _legacy_C_ops.mish(x, 'threshold', threshold)
9676

K
Kaipeng Deng 已提交
9677 9678
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'mish')
    check_type(threshold, 'threshold', (float, int), 'mish')
9679 9680 9681 9682 9683
    assert (
        threshold > 0
    ), "threshold of mish should be greater than 0, " "but got {}".format(
        threshold
    )
K
Kaipeng Deng 已提交
9684 9685 9686

    helper = LayerHelper('mish', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
9687 9688 9689 9690 9691 9692
    helper.append_op(
        type='mish',
        inputs={'X': x},
        outputs={'Out': out},
        attrs={'threshold': threshold},
    )
K
Kaipeng Deng 已提交
9693 9694 9695
    return out


G
Guo Sheng 已提交
9696
def gather_tree(ids, parents):
9697
    r"""
G
Guo Sheng 已提交
9698 9699 9700 9701 9702 9703 9704 9705 9706 9707 9708 9709 9710 9711 9712 9713 9714 9715 9716 9717 9718 9719 9720 9721
    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]]]

9722 9723
            Then:
                gather_tree(ids, parents)
G
Guo Sheng 已提交
9724 9725 9726 9727 9728 9729 9730 9731
                         = [[[2 2]
                             [1 6]]
                            [[3 3]
                             [6 1]]
                            [[0 1]
                             [9 0]]]

    Args:
L
liu zhengxi 已提交
9732
        ids(Tensor): A Tensor with shape :attr:`[length, batch_size, beam_size]`
G
Guo Sheng 已提交
9733 9734
            and data type :attr:`int32` or :attr:`int64`. It contains the selected
            ids of all time steps.
L
liu zhengxi 已提交
9735
        parents(Tensor): A Tensor with the same shape and data type as :attr:`ids`,
G
Guo Sheng 已提交
9736 9737 9738 9739
            It contains the parents corresponding to selected ids when searching
            among beams.

    Returns:
L
liu zhengxi 已提交
9740
            A Tensor with the same shape and data type as :attr:`ids`. \
G
Guo Sheng 已提交
9741 9742 9743 9744 9745 9746
            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 已提交
9747 9748 9749 9750 9751 9752 9753 9754
            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 已提交
9755 9756

    """
9757
    return paddle.nn.functional.gather_tree(ids, parents)
G
Guo Sheng 已提交
9758 9759


9760
@deprecated(since="2.0.0", update_to="paddle.uniform")
9761
@templatedoc()
9762 9763 9764
def uniform_random(
    shape, dtype='float32', min=-1.0, max=1.0, seed=0, name=None
):
9765
    """
9766 9767
    This OP returns a Tensor filled with random values sampled from a uniform
    distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.
9768 9769 9770

    Examples:
    ::
9771

9772 9773
        Input:
          shape = [1, 2]
9774

9775 9776 9777 9778
        Output:
          result=[[0.8505902, 0.8397286]]

    Args:
9779 9780 9781 9782 9783 9784 9785 9786 9787 9788 9789 9790 9791
        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
9792 9793
            use a seed generated by the system. Note that if seed is not 0,
            this operator will always generate the same random numbers every
9794
            time. Default is 0.
9795 9796 9797
        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`.
9798

9799
    Returns:
9800 9801
        Tensor: A Tensor filled with random values sampled from a uniform
        distribution in the range [``min``, ``max``), with ``shape`` and ``dtype``.
9802

9803
    Raises:
9804 9805
        TypeError: If ``shape`` is not list, tuple, Tensor.
        TypeError: If ``dtype`` is not float32, float64.
9806

9807 9808 9809
    Examples:
        .. code-block:: python

9810
            import paddle
9811
            import paddle.fluid as fluid
9812
            paddle.enable_static()
9813 9814

            # example 1:
9815
            # attr shape is a list which doesn't contain Tensor.
9816
            result_1 = fluid.layers.uniform_random(shape=[3, 4])
9817 9818 9819
            # [[ 0.84524226,  0.6921872,   0.56528175,  0.71690357],
            #  [-0.34646994, -0.45116323, -0.09902662, -0.11397249],
            #  [ 0.433519,    0.39483607, -0.8660099,   0.83664286]]
9820 9821

            # example 2:
9822 9823 9824
            # 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)
9825
            result_2 = fluid.layers.uniform_random(shape=[dim_1, dim_2])
9826 9827
            # [[-0.9951253,   0.30757582, 0.9899647 ],
            #  [ 0.5864527,   0.6607096,  -0.8886161 ]]
9828 9829

            # example 3:
9830
            # attr shape is a Tensor, the data type must be int64 or int32.
9831
            var_shape = fluid.data(name='var_shape', shape=[2], dtype="int64")
9832
            result_3 = fluid.layers.uniform_random(var_shape)
9833 9834 9835 9836
            # if var_shape's value is [2, 3]
            # result_3 is:
            # [[-0.8517412,  -0.4006908,   0.2551912 ],
            #  [ 0.3364414,   0.36278176, -0.16085452]]
9837

9838 9839 9840
    """
    if not isinstance(dtype, core.VarDesc.VarType):
        dtype = convert_np_dtype_to_dtype_(dtype)
9841

9842 9843
    if in_dygraph_mode():
        shape = utils.convert_shape_to_list(shape)
9844
        return _C_ops.uniform(
9845 9846 9847 9848 9849 9850 9851
            shape,
            dtype,
            float(min),
            float(max),
            seed,
            _current_expected_place(),
        )
9852
    elif _in_legacy_dygraph():
9853
        shape = utils.convert_shape_to_list(shape)
9854 9855 9856 9857 9858 9859 9860 9861 9862 9863 9864 9865
        return _legacy_C_ops.uniform_random(
            'shape',
            shape,
            'min',
            float(min),
            'max',
            float(max),
            'seed',
            seed,
            'dtype',
            dtype,
        )
9866

9867
    check_type(shape, 'shape', (list, tuple, Variable), 'uniform_random/rand')
9868 9869 9870
    check_dtype(
        dtype, 'dtype', ('float32', 'float64', 'uint16'), 'uniform_random/rand'
    )
9871 9872
    check_type(min, 'min', (float, int, Variable), 'uniform_random/rand')
    check_type(max, 'max', (float, int, Variable), 'uniform_random/rand')
9873 9874

    inputs = dict()
9875
    attrs = {'seed': seed, 'min': min, 'max': max, 'dtype': dtype}
9876 9877 9878
    utils.get_shape_tensor_inputs(
        inputs=inputs, attrs=attrs, shape=shape, op_type='uniform_random/rand'
    )
9879

9880
    helper = LayerHelper("uniform_random", **locals())
9881
    out = helper.create_variable_for_type_inference(dtype)
9882 9883 9884
    helper.append_op(
        type="uniform_random", inputs=inputs, attrs=attrs, outputs={"Out": out}
    )
9885
    utils.try_set_static_shape_tensor(out, shape)
9886
    return out
myq406450149's avatar
myq406450149 已提交
9887 9888 9889 9890 9891 9892 9893


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

myq406450149's avatar
myq406450149 已提交
9895 9896 9897 9898 9899 9900 9901 9902 9903 9904 9905 9906 9907 9908 9909 9910 9911 9912 9913 9914 9915 9916 9917 9918 9919
        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()
9920 9921 9922
    check_dtype(
        dtype, 'unbind', ['float32', 'float64', 'int32', 'int64'], 'unbind'
    )
myq406450149's avatar
myq406450149 已提交
9923
    if not isinstance(axis, (int)):
9924 9925 9926
        raise TypeError(
            "The type of 'axis'  must be int, but received %s." % (type(axis))
        )
myq406450149's avatar
myq406450149 已提交
9927 9928 9929 9930 9931 9932 9933 9934 9935 9936
    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)
    ]

9937 9938 9939 9940 9941 9942
    helper.append_op(
        type="unbind",
        inputs={"X": input},
        outputs={"Out": outs},
        attrs={"axis": axis},
    )
myq406450149's avatar
myq406450149 已提交
9943
    return outs