from __future__ import print_function import paddle import paddle.fluid as fluid from paddle.fluid import core from paddle.fluid.layer_helper import LayerHelper from paddle.fluid.dygraph.layer_object_helper import LayerObjectHelper from paddle.fluid.initializer import Normal, Constant, NumpyArrayInitializer from paddle.fluid.param_attr import ParamAttr from paddle.fluid.framework import Variable, OpProtoHolder, in_dygraph_mode from paddle.fluid.layers import utils import numpy as np import paddle import paddle.fluid as fluid from paddle.fluid import core from paddle.fluid.initializer import Normal, Constant, NumpyArrayInitializer from paddle.fluid.dygraph import dygraph_utils from paddle.fluid.framework import Variable, OpProtoHolder, in_dygraph_mode from paddle.fluid.layers import utils def Fconv2d( input, filter, stride=1, padding=0, dilation=1, groups=1, use_cudnn=True, ): """ Similar with conv2d, this is a convolution2D layers. Difference is filter can be token as input directly instead of setting filter size and number of fliters. Filter is a 4-D tensor with shape [num_filter, num_channel, filter_size_h, filter_size_w]. Args: input (Variable): The input image with [N, C, H, W] format. filter(Variable): The input filter with [out_channels, in_channels, H, W] format. stride (int|tuple): The stride size. If stride is a tuple, it must contain two integers, (stride_H, stride_W). Otherwise, the stride_H = stride_W = stride. Default: stride = 1. padding (int|tuple): The padding size. If padding is a tuple, it must contain two integers, (padding_H, padding_W). Otherwise, the padding_H = padding_W = padding. Default: padding = 0. dilation (int|tuple): The dilation size. If dilation is a tuple, it must contain two integers, (dilation_H, dilation_W). Otherwise, the dilation_H = dilation_W = dilation. Default: dilation = 1. 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. use_cudnn (bool): Use cudnn kernel or not, it is valid only when the cudnn library is installed. Default: True act (str): Activation type, if it is set to None, activation is not appended. Default: None name (str|None): A name for this layer(optional). If set None, the layer will be named automatically. Default: None Returns: Variable: The tensor variable storing the convolution and \ non-linearity activation result. Raises: ValueError: If the shapes of input, filter_size, stride, padding and groups mismatch. Examples: .. code-block:: python data = fluid.data(name='data', shape=[None, 3, 32, 32], \ dtype='float32') filter = fluid.data(name='filter',shape=[10,3,3,3], \ dtype='float32') conv2d = fluid.layers.conv2d(input=data, filter=filter, act="relu") """ conv_with_filter = Conv2D( stride=stride, padding=padding, dilation=dilation, groups=groups) return conv_with_filter(input, filter) class Conv2D(fluid.dygraph.layers.Layer): """ This interface is used to construct a callable object of the ``Conv2D`` class. For more details, refer to code examples. The convolution2D layer calculates the output based on the input, filter and strides, paddings, dilations, groups parameters. Input and Output are in NCHW format, where N is batch size, C is the number of the feature map, H is the height of the feature map, and W is the width of the feature map. Filter's shape is [MCHW] , where M is the number of output feature map, C is the number of input feature map, 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 feature map divided by the groups. Please refer to UFLDL's `convolution `_ for more detials. 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. For each input :math:`X`, the equation is: .. math:: Out = \\sigma (W \\ast X + b) Where: * :math:`X`: Input value, a ``Tensor`` with NCHW format. * :math:`W`: Filter value, a ``Tensor`` with shape [MCHW] . * :math:`\\ast`: Convolution operation. * :math:`b`: Bias value, a 2-D ``Tensor`` with shape [M, 1]. * :math:`\\sigma`: Activation function. * :math:`Out`: Output value, the shape of :math:`Out` and :math:`X` may be different. Example: - Input: Input shape: :math:`(N, C_{in}, H_{in}, W_{in})` Filter shape: :math:`(C_{out}, C_{in}, H_f, W_f)` - Output: Output shape: :math:`(N, C_{out}, H_{out}, W_{out})` Where .. math:: 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 Parameters: num_channels(int): The number of channels in the input image. num_filters(int): The number of filter. It is as same as the output feature map. filter_size (int or tuple): The filter size. If filter_size is a tuple, it must contain two integers, (filter_size_H, filter_size_W). Otherwise, the filter will be a square. stride (int or tuple, optional): The stride size. If stride is a tuple, it must contain two integers, (stride_H, stride_W). Otherwise, the stride_H = stride_W = stride. Default: 1. padding (int or tuple, optional): The padding size. If padding is a tuple, it must contain two integers, (padding_H, padding_W). Otherwise, the padding_H = padding_W = padding. Default: 0. dilation (int or tuple, optional): The dilation size. If dilation is a tuple, it must contain two integers, (dilation_H, dilation_W). Otherwise, the dilation_H = dilation_W = dilation. Default: 1. groups (int, optional): 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 connected to the second half of the input channels. Default: 1. param_attr (ParamAttr, optional): The parameter attribute for learnable weights(Parameter) 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)`, and the :math:`std` is :math:`(\\frac{2.0 }{filter\_elem\_num})^{0.5}`. Default: None. bias_attr (ParamAttr or bool, optional): The 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. use_cudnn (bool, optional): Use cudnn kernel or not, it is valid only when the cudnn library is installed. Default: True. act (str, optional): Activation type, if it is set to None, activation is not appended. Default: None. dtype (str, optional): Data type, it can be "float32" or "float64". Default: "float32". Attribute: **weight** (Parameter): the learnable weights of filter of this layer. **bias** (Parameter or None): the learnable bias of this layer. Returns: None Raises: ValueError: if ``use_cudnn`` is not a bool value. Examples: .. code-block:: python from paddle.fluid.dygraph.base import to_variable import paddle.fluid as fluid from paddle.fluid.dygraph import Conv2D import numpy as np data = np.random.uniform(-1, 1, [10, 3, 32, 32]).astype('float32') with fluid.dygraph.guard(): conv2d = Conv2D(3, 2, 3) data = to_variable(data) conv = conv2d(data) """ def __init__(self, stride=1, padding=0, dilation=1, groups=None, use_cudnn=True, act=None, dtype='float32'): super(Conv2D, self).__init__() self._groups = groups self._stride = utils.convert_to_list(stride, 2, 'stride') self._padding = utils.convert_to_list(padding, 2, 'padding') self._dilation = utils.convert_to_list(dilation, 2, 'dilation') self._act = act if not isinstance(use_cudnn, bool): raise ValueError("use_cudnn should be True or False") self._use_cudnn = use_cudnn self._dtype = dtype # TODO: recover the usage of depthwise_conv2d when it's # kernel fixed https://github.com/PaddlePaddle/Paddle/issues/17098 # if (self._num_channels == self._groups and # num_filters % self._num_channels == 0 and not self._use_cudnn): # self._l_type = 'depthwise_conv2d' # else: # self._l_type = 'conv2d' self._l_type = 'conv2d' def forward(self, input, weight, bias=None): inputs = { 'Input': [input], 'Filter': [weight], } attrs = { 'strides': self._stride, 'paddings': self._padding, 'dilations': self._dilation, 'groups': self._groups if self._groups else 1, 'use_cudnn': self._use_cudnn, 'use_mkldnn': False, } if in_dygraph_mode(): outs = core.ops.conv2d(inputs, attrs) pre_bias = outs['Output'][0] pre_act = dygraph_utils._append_bias_in_dygraph(pre_bias, bias, 1) return dygraph_utils._append_activation_in_dygraph(pre_act, self._act) pre_bias = self._helper.create_variable_for_type_inference( dtype=self._dtype) self._helper.append_op( type=self._l_type, inputs={ 'Input': input, 'Filter': weight, }, outputs={"Output": pre_bias}, attrs=attrs) if bias is not None: pre_act = self._helper.create_variable_for_type_inference( dtype=self._dtype) self._helper.append_op( type='elementwise_add', inputs={'X': [pre_bias], 'Y': [bias]}, outputs={'Out': [pre_act]}, attrs={'axis': 1}) else: pre_act = pre_bias # Currently, we don't support inplace in dygraph mode return self._helper.append_activation(pre_act, act=self._act)