def update_padding(padding, data_format): """ update_padding: convert to 2-dimension padding """ def is_list_or_tuple(ele): """ return true if ele is list or tuple. """ if isinstance(ele, list) or isinstance(ele, tuple): return True return False # covert padding size to 2 (H, W) if is_list_or_tuple(padding) and len(padding) == 4: if is_list_or_tuple(padding[0]): if not (padding[0] == [0, 0] and padding[1] == [0, 0]): raise ValueError( "Non-zero pool_padding(%s) in the batch or channel dimensions " "is not supported." % str(padding)) padding = padding[2:4] # data_format == "NCHW": padding = [ele for a_list in padding for ele in a_list] padding = utils.convert_to_list(padding, 4, 'padding') if utils._is_symmetric_padding(padding, 2): padding = [padding[0], padding[2]] else: padding = utils.convert_to_list(padding, 2, 'padding') return padding
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 deform_conv2d(x, offset, weight, mask, bias=None, stride=1, padding=0, dilation=1, deformable_groups=1, groups=1, name=None): stride = utils.convert_to_list(stride, 2, 'stride') padding = utils.convert_to_list(padding, 2, 'padding') dilation = utils.convert_to_list(dilation, 2, 'dilation') use_deform_conv2d_v1 = True if mask is None else False if in_dygraph_mode(): attrs = ('strides', stride, 'paddings', padding, 'dilations', dilation, 'deformable_groups', deformable_groups, 'groups', groups, 'im2col_step', 1) if use_deform_conv2d_v1: op_type = 'deformable_conv_v1' pre_bias = getattr(core.ops, op_type)(x, offset, weight, *attrs) else: op_type = 'deformable_conv' pre_bias = getattr(core.ops, op_type)(x, offset, mask, weight, *attrs) if bias is not None: out = nn.elementwise_add(pre_bias, bias, axis=1) else: out = pre_bias return out
def __init__(self, pool_size=-1, pool_type="max", pool_stride=1, pool_padding=0, global_pooling=False, use_cudnn=True, ceil_mode=False, exclusive=True): if pool_type not in ["max", "avg"]: raise ValueError( "Unknown pool_type: '%s'. It can only be 'max' or 'avg'.", str(pool_type)) if global_pooling is False and pool_size == -1: raise ValueError( "When the global_pooling is False, pool_size must be passed " "and be a valid value. Received pool_size: " + str(pool_size)) if not isinstance(use_cudnn, bool): raise ValueError("use_cudnn should be True or False") super(Pool3D, self).__init__() self._pool_type = pool_type self._pool_size = utils.convert_to_list(pool_size, 3, 'pool_size') self._pool_padding = utils.convert_to_list(pool_padding, 3, 'pool_padding') self._pool_stride = utils.convert_to_list(pool_stride, 3, 'pool_stride') self._global_pooling = global_pooling self._use_cudnn = use_cudnn self._ceil_mode = ceil_mode self._exclusive = exclusive self._l_type = 'pool3d'
def _conv3d(x, weight, bias=None, stride=1, padding=0, dilation=1, groups=1, subm=False, data_format="NDHWC", name=None): assert in_dynamic_mode(), "Currently, only support dynamic mode" assert groups == 1, "Currently, only support groups=1" dims = 3 # Currently, only support 'NDHWC' if data_format not in ["NDHWC"]: raise ValueError("Attr(data_format) should be 'NDHWC'. Received " "Attr(data_format): {}.".format(data_format)) if len(x.shape) != 5: raise ValueError( "Input x should be 5D tensor, but received x with the shape of {}". format(x.shape)) channel_last = (data_format == "NDHWC") channel_dim = -1 if channel_last else 1 if len(x.shape) != 5: raise ValueError( "Input x should be 5D tensor, but received x with the shape of {}". format(x.shape)) num_channels = x.shape[channel_dim] if num_channels < 0: raise ValueError( "The channel dimension of the input({}) should be defined. " "Received: {}.".format(x.shape, num_channels)) padding, padding_algorithm = _update_padding_nd(padding, channel_last, dims) stride = convert_to_list(stride, dims, 'stride') dilation = convert_to_list(dilation, dims, 'dilation') op_type = "conv3d" pre_bias = _C_ops.final_state_sparse_conv3d(x, weight, padding, dilation, stride, groups, subm) if bias is not None: values = pre_bias.values() add_bias = elementwise_add(values, bias, axis=1) return sparse_coo_tensor(pre_bias.indices(), add_bias, shape=pre_bias.shape, stop_gradient=pre_bias.stop_gradient) else: return pre_bias
def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, deformable_groups=1, groups=1, weight_attr=None, bias_attr=None): super(DeformConv2D, self).__init__() assert weight_attr is not False, "weight_attr should not be False in Conv." self._weight_attr = weight_attr self._bias_attr = bias_attr self._deformable_groups = deformable_groups self._groups = groups self._in_channels = in_channels self._out_channels = out_channels self.padding = padding self.stride = stride self._channel_dim = 1 self._stride = utils.convert_to_list(stride, 2, 'stride') self._dilation = utils.convert_to_list(dilation, 2, 'dilation') self._kernel_size = utils.convert_to_list(kernel_size, 2, 'kernel_size') if in_channels % groups != 0: raise ValueError("in_channels must be divisible by groups.") self._padding = utils.convert_to_list(padding, 2, 'padding') filter_shape = [out_channels, in_channels // groups ] + self._kernel_size def _get_default_param_initializer(): filter_elem_num = np.prod(self._kernel_size) * self._in_channels std = (2.0 / filter_elem_num)**0.5 return Normal(0.0, std, 0) self.weight = self.create_parameter( shape=filter_shape, attr=self._weight_attr, default_initializer=_get_default_param_initializer()) self.bias = self.create_parameter(attr=self._bias_attr, shape=[self._out_channels], is_bias=True)
def _update_padding_nd(padding, channel_last, num_dims): if isinstance(padding, str): padding = padding.upper() if padding not in ["SAME", "VALID"]: raise ValueError( "Unknown padding: '{}'. It can only be 'SAME' or 'VALID'.". format(padding)) if padding == "VALID": padding_algorithm = "VALID" padding = [0] * num_dims else: padding_algorithm = "SAME" padding = [0] * num_dims elif _is_list_or_tuple(padding): # for padding like # [(pad_before, pad_after), (pad_before, pad_after), ...] # padding for batch_dim and channel_dim included if len(padding) == 2 + num_dims and _is_list_or_tuple(padding[0]): if not _zero_padding_in_batch_and_channel(padding, channel_last): raise ValueError( "Non-zero padding({}) in the batch or channel dimensions " "is not supported.".format(padding)) padding_algorithm = "EXPLICIT" padding = _exclude_padding_in_batch_and_channel(padding, channel_last) if utils._is_symmetric_padding(padding, num_dims): padding = padding[0::2] # for padding like [pad_before, pad_after, pad_before, pad_after, ...] elif len(padding) == 2 * num_dims and isinstance(padding[0], int): padding_algorithm = "EXPLICIT" padding = utils.convert_to_list(padding, 2 * num_dims, 'padding') if utils._is_symmetric_padding(padding, num_dims): padding = padding[0::2] # for padding like [pad_d1, pad_d2, ...] elif len(padding) == num_dims and isinstance(padding[0], int): padding_algorithm = "EXPLICIT" padding = utils.convert_to_list(padding, num_dims, 'padding') else: raise ValueError("In valid padding: {}".format(padding)) # for integer padding else: padding_algorithm = "EXPLICIT" padding = utils.convert_to_list(padding, num_dims, 'padding') return padding, padding_algorithm
def _build_once(self, input): self._num_channels = input.shape[1] if self._groups is None: num_filter_channels = self._num_channels else: if self._num_channels % self._groups != 0: raise ValueError("num_channels must be divisible by groups.") num_filter_channels = self._num_channels // self._groups filter_size = utils.convert_to_list(self._filter_size, 2, "filter_size") filter_shape = [self._num_filters, int(num_filter_channels) ] + filter_size def _get_default_param_initializer(): filter_elem_num = filter_size[0] * filter_size[ 1] * self._num_channels std = (2.0 / filter_elem_num)**0.5 return Normal(0.0, std, 0) # weight_v self._filter_param_v = self.create_parameter( attr=self._param_attr, shape=filter_shape, dtype=self._dtype, default_initializer=_get_default_param_initializer()) # weight_g norm_value = _norm( self._filter_param_v.numpy(), dim=0) # CAUTION: hard-code self._filter_param_g = self.create_parameter( attr=fluid.ParamAttr( initializer=fluid.initializer.NumpyArrayInitializer( norm_value)), shape=norm_value.shape, dtype=self._dtype, default_initializer=_get_default_param_initializer()) if self._use_cudnn: self.create_variable( name="kCUDNNFwdAlgoCache", persistable=True, type=core.VarDesc.VarType.RAW) self.create_variable( name="kCUDNNBwdDataAlgoCache", persistable=True, type=core.VarDesc.VarType.RAW) self.create_variable( name="kCUDNNBwdFilterAlgoCache", persistable=True, type=core.VarDesc.VarType.RAW) self._bias_param = self.create_parameter( attr=self._bias_attr, shape=[self._num_filters], dtype=self._dtype, is_bias=True)
def __init__(self, name_scope, num_filters, filter_size, stride=1, padding=0, dilation=1, groups=None, param_attr=None, bias_attr=None, use_cudnn=True, act=None, epsilon=1e-30, dtype="float32"): assert param_attr is not False, "param_attr should not be False here." super(Conv2D, self).__init__(name_scope, dtype) 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._filter_size = filter_size self._num_filters = num_filters self._param_attr = param_attr self._bias_attr = bias_attr self._epsilon = epsilon self._dtype = dtype # if (self._num_channels == self._groups and # num_filters % self._num_channels == 0 and not self._use_cudnn): # self._l_type = 'depthwise_conv2d' # else: # TODO(jiabin): recover the usage of depthwise_conv2d when it's # kernel fixed https://github.com/PaddlePaddle/Paddle/issues/17275 self._l_type = "conv2d"
def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, subm=False, padding_mode='zeros', weight_attr=None, bias_attr=None, data_format="NDHWC"): super(_Conv3D, self).__init__() assert weight_attr is not False, "weight_attr should not be False in Conv." self._param_attr = weight_attr self._bias_attr = bias_attr self._groups = groups self._in_channels = in_channels self._out_channels = out_channels self._data_format = data_format self._subm = subm assert padding_mode == 'zeros', "Currently, only support padding_mode='zeros'" assert groups == 1, "Currently, only support groups=1" valid_format = {'NDHWC'} if data_format not in valid_format: raise ValueError( "data_format must be one of {}, but got data_format='{}'". format(valid_format, data_format)) channel_last = data_format == "NDHWC" dims = 3 self._stride = utils.convert_to_list(stride, dims, 'stride') self._dilation = utils.convert_to_list(dilation, dims, 'dilation') self._kernel_size = utils.convert_to_list(kernel_size, dims, 'kernel_size') self._padding = padding self._padding_mode = padding_mode self._updated_padding, self._padding_algorithm = _update_padding_nd( padding, channel_last, dims) # the sparse conv restricts the shape is [D, H, W, in_channels, out_channels] filter_shape = self._kernel_size + [ self._in_channels, self._out_channels ] def _get_default_param_initializer(): filter_elem_num = np.prod(self._kernel_size) * self._in_channels std = (2.0 / filter_elem_num)**0.5 return Normal(0.0, std) self.weight = self.create_parameter( shape=filter_shape, attr=self._param_attr, default_initializer=_get_default_param_initializer()) #self.bias = self.create_parameter( # attr=self._bias_attr, shape=[self._out_channels], is_bias=True) self.bias = None
def _build_once(self, input): input_channel = input.shape[1] if (input_channel == self._groups and self._num_filters == input_channel and not self._use_cudnn): self._op_type = "depthwise_conv2d_transpose" if not isinstance(input, Variable): raise TypeError("Input of conv2d_transpose must be Variable") self._padding = utils.convert_to_list(self._padding, 2, "padding") self._stride = utils.convert_to_list(self._stride, 2, "stride") self._dilation = utils.convert_to_list(self._dilation, 2, "dilation") if not isinstance(self._use_cudnn, bool): raise ValueError("use_cudnn should be True or False") if self._filter_size is None: if self._output_size is None: raise ValueError( "output_size must be set when filter_size is None") if isinstance(self._output_size, int): self._output_size = [self._output_size, self._output_size] h_in = input.shape[2] w_in = input.shape[3] filter_size_h = (self._output_size[0] - (h_in - 1) * self._stride[0] + 2 * self._padding[0] - 1) // self._dilation[0] + 1 filter_size_w = (self._output_size[1] - (w_in - 1) * self._stride[1] + 2 * self._padding[1] - 1) // self._dilation[1] + 1 self._filter_size = [filter_size_h, filter_size_w] else: self._filter_size = utils.convert_to_list( self._filter_size, 2, "conv2d_transpose.filter_size") if self._output_size is None: self._output_size = [] elif isinstance(self._output_size, list) or isinstance( self._output_size, int): self._output_size = utils.convert_to_list(self._output_size, 2, "output_size") else: raise ValueError("output_size should be list or int") self._padding = utils.convert_to_list(self._padding, 2, "padding") self._groups = 1 if self._groups is None else self._groups filter_shape = [ input_channel, self._num_filters // self._groups, ] + self._filter_size # img filter v (direction) self._img_filter_v = self.create_parameter( dtype=input.dtype, shape=filter_shape, attr=self._param_attr) # img filter g (magnitude) img_filter_magnitude = _norm( self._img_filter_v.numpy(), dim=0) # CAUTION: hard-code self._img_filter_g = self.create_parameter( dtype=input.dtype, shape=img_filter_magnitude.shape, attr=fluid.ParamAttr( initializer=NumpyArrayInitializer(img_filter_magnitude))) self._img_bias = self.create_parameter( attr=self._bias_attr, shape=[self._num_filters], dtype=self._dtype, is_bias=True)
def __init__(self, num_channels_x, num_filters, filter_size, stride=1, momentum=0.9, eps=1e-5, data_format='NHWC', act='relu', fuse_add=False, has_shortcut=False, use_global_stats=False, is_test=False, filter_x_attr=None, scale_x_attr=None, bias_x_attr=None, moving_mean_x_name=None, moving_var_x_name=None, num_channels_z=1, stride_z=1, filter_z_attr=None, scale_z_attr=None, bias_z_attr=None, moving_mean_z_name=None, moving_var_z_name=None): super(ResNetUnit, self).__init__() self._stride = stride self._stride_z = stride_z self._dilation = 1 self._kernel_size = utils.convert_to_list(filter_size, 2, 'kernel_size') self._padding = (filter_size - 1) // 2 self._groups = 1 self._momentum = momentum self._eps = eps self._data_format = data_format self._act = act self._fuse_add = fuse_add self._has_shortcut = has_shortcut self._use_global_stats = use_global_stats self._is_test = is_test # check format valid_format = {'NHWC'} if data_format not in valid_format: raise ValueError( "conv_format must be one of {}, but got conv_format='{}'". format(valid_format, data_format)) def _get_default_param_initializer(channels): filter_elem_num = np.prod(self._kernel_size) * channels std = (2.0 / filter_elem_num)**0.5 return I.Normal(0.0, std) # initial filter bn_param_dtype = fluid.core.VarDesc.VarType.FP32 bn_param_shape = [1, 1, 1, num_filters] filter_x_shape = [ num_filters, filter_size, filter_size, num_channels_x ] filter_z_shape = [ num_filters, filter_size, filter_size, num_channels_z ] self.filter_x = self.create_parameter( shape=filter_x_shape, attr=filter_x_attr, default_initializer=_get_default_param_initializer(num_channels_x)) self.scale_x = self.create_parameter( shape=bn_param_shape, attr=scale_x_attr, dtype=bn_param_dtype, default_initializer=I.Constant(1.0)) self.bias_x = self.create_parameter(shape=bn_param_shape, attr=bias_x_attr, dtype=bn_param_dtype, is_bias=True) self.mean_x = self.create_parameter(attr=ParamAttr( name=moving_mean_x_name, initializer=I.Constant(0.0), trainable=False), shape=bn_param_shape, dtype=bn_param_dtype) self.mean_x.stop_gradient = True self.var_x = self.create_parameter(attr=ParamAttr( name=moving_var_x_name, initializer=I.Constant(1.0), trainable=False), shape=bn_param_shape, dtype=bn_param_dtype) self.var_x.stop_gradient = True if has_shortcut: self.filter_z = self.create_parameter( shape=filter_z_shape, attr=filter_z_attr, default_initializer=_get_default_param_initializer( num_channels_z)) self.scale_z = self.create_parameter( shape=bn_param_shape, attr=scale_z_attr, dtype=bn_param_dtype, default_initializer=I.Constant(1.0)) self.bias_z = self.create_parameter(shape=bn_param_shape, attr=bias_z_attr, dtype=bn_param_dtype, is_bias=True) self.mean_z = self.create_parameter(attr=ParamAttr( name=moving_mean_z_name, initializer=I.Constant(0.0), trainable=False), shape=bn_param_shape, dtype=bn_param_dtype) self.mean_z.stop_gradient = True self.var_z = self.create_parameter(attr=ParamAttr( name=moving_var_z_name, initializer=I.Constant(1.0), trainable=False), shape=bn_param_shape, dtype=bn_param_dtype) self.var_z.stop_gradient = True else: self.filter_z = None self.scale_z = None self.bias_z = None self.mean_z = None self.var_z = None
def pool2d(input, pool_size=-1, pool_type="max", pool_stride=1, pool_padding=0, global_pooling=False, ceil_mode=False, name=None, exclusive=True, data_format="NCHW"): """ pool2d """ if pool_type not in ["max"]: raise ValueError( "Unknown Attr(pool_type): '%s'. It can only be 'max'.", str(pool_type)) if global_pooling is False and pool_size == -1: raise ValueError( "When Attr(global_pooling) is False, Attr(pool_size) must be passed " "and be a valid value. Received pool_size: %s." % str(pool_size)) if data_format not in ["NCHW"]: raise ValueError("Attr(data_format) should be 'NCHW'. Received " "Attr(data_format): %s." % str(data_format)) pool_size = utils.convert_to_list(pool_size, 2, 'pool_size') pool_stride = utils.convert_to_list(pool_stride, 2, 'pool_stride') def update_padding(padding, data_format): """ update_padding: convert to 2-dimension padding """ def is_list_or_tuple(ele): """ return true if ele is list or tuple. """ if isinstance(ele, list) or isinstance(ele, tuple): return True return False # covert padding size to 2 (H, W) if is_list_or_tuple(padding) and len(padding) == 4: if is_list_or_tuple(padding[0]): if not (padding[0] == [0, 0] and padding[1] == [0, 0]): raise ValueError( "Non-zero pool_padding(%s) in the batch or channel dimensions " "is not supported." % str(padding)) padding = padding[2:4] # data_format == "NCHW": padding = [ele for a_list in padding for ele in a_list] padding = utils.convert_to_list(padding, 4, 'padding') if utils._is_symmetric_padding(padding, 2): padding = [padding[0], padding[2]] 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'." % str(pool_padding)) if pool_padding == "VALID": padding_algorithm = "VALID" pool_padding = [0, 0] if ceil_mode != False: raise ValueError( "When Attr(pool_padding) is \"VALID\", Attr(ceil_mode) must be False. " "Received ceil_mode: True.") elif pool_padding == "SAME": padding_algorithm = "SAME" pool_padding = [0, 0] pool_padding = update_padding(pool_padding, data_format) # [h, w] op_type = 'pool2d' helper = MpcLayerHelper(op_type, **locals()) dtype = helper.input_dtype() pool_out = helper.create_mpc_variable_for_type_inference(dtype) one_hot_tensor = helper.create_variable_for_type_inference( dtype=input.dtype) helper.append_op(type='mpc_' + op_type, inputs={"X": input}, outputs={ "Out": pool_out, "One_hot_tensor": one_hot_tensor }, attrs={ "pooling_type": pool_type, "ksize": pool_size, "global_pooling": global_pooling, "strides": pool_stride, "paddings": pool_padding, "padding_algorithm": padding_algorithm, "ceil_mode": ceil_mode, "exclusive": exclusive, "data_format": data_format, }) return pool_out
def var_conv_2d(input, row, col, input_channel, output_channel, filter_size, stride=1, param_attr=None, act=None, dtype='float32', name=None): """ The var_conv_2d layer calculates the output base on the :attr:`input` with variable length, row, col, input channel, filter size and strides. Both :attr:`input`, :attr:`row`, and :attr:`col` are 1-level LodTensor. The convolution operation is same as conv2d layer with padding. Besides, input.dims[1] should be 1. .. code-block:: text If input_channel is 2 and given row lodTensor and col lodTensor as follows: row.lod = [[5, 4]] col.lod = [[6, 7]] input is a lodTensor: input.lod = [[60, 56]] # where 60 = input_channel * 5 * 6 input.dims = [116, 1] # where 116 = 60 + 56 If set output_channel is 3, filter_size is [3, 3], stride is [1, 1]: # where 90 = output_channel * [(5-1)/stride + 1] * [(6-1)/stride + 1] output.lod = [[90, 84]] output.dims = [174, 1] # where 174 = 90 + 84 Args: input (Variable): The input should be 1-level LodTensor with dims[1] equals 1. row (Variable): The row should be 1-level LodTensor to provide height information. col (Variable): The col should be 1-level LodTensor to provide width information. input_channel (int): The number of input channel. output_channel (int): The number of output channel. filter_size (int|tuple|None): 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|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. param_attr (ParamAttr|None): The parameter attribute for learnable parameters/weights of var_conv2d. If it is set to None or one attribute of ParamAttr, var_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. act (str): Activation type, if it is set to None, activation is not appended. Default: None dtype ('float32'): The data type of parameter and output. name (str|None): A name for this layer(optional). If set None, the layer will be named automatically. Default: None Returns: Variable: Output variable with LoD specified by this layer. Examples: .. code-block:: python import numpy as np from paddle.fluid import layers from paddle.fluid import contrib x_lod_tensor = layers.data(name='x', shape=[1], lod_level=1) row_lod_tensor = layers.data(name='row', shape=[6], lod_level=1) col_lod_tensor = layers.data(name='col', shape=[6], lod_level=1) out = contrib.var_conv_2d(input=x_lod_tensor, row=row_lod_tensor, col=col_lod_tensor, input_channel=3, output_channel=5, filter_size=[3, 3], stride=1) """ helper = LayerHelper('var_conv_2d', **locals()) x_shape = list(input.shape) assert len(x_shape) == 2 filter_size = utils.convert_to_list(filter_size, 2, 'filter_size') stride = utils.convert_to_list(stride, 2, 'stride') filter_shape = [ int(output_channel), int(input_channel) * filter_size[0] * filter_size[1] ] filter_param = helper.create_parameter( attr=helper.param_attr, shape=filter_shape, dtype=dtype, ) conv_res = helper.create_variable_for_type_inference(dtype) tmp_res = helper.create_variable_for_type_inference(dtype, stop_gradient=True) helper.append_op(type='var_conv_2d', inputs={ 'X': input, 'ROW': row, 'COLUMN': col, 'W': filter_param, }, outputs={ "Out": conv_res, "Col": tmp_res }, attrs={ 'InputChannel': input_channel, 'OutputChannel': output_channel, 'StrideH': stride[0], 'StrideW': stride[1], 'KernelH': filter_size[0], 'KernelW': filter_size[1], }) return helper.append_activation(conv_res)
def max_pool3d(x, kernel_size, stride=None, padding=0, ceil_mode=False, data_format="NDHWC", name=None): """ Implements sparse max pooling 3d operation. See more details in :ref:`api_sparse_pooling_MaxPool3d` . Args: x (Tensor): The input SparseCooTensor of pooling operator, which is a 5-D tensor with shape [N, D, H, W, C]. The format of input tensor `"NDHWC"`, where N represents batch size, C represents the number of channels, D, H and W represent the depth, height and width of the feature respectively. kernel_size (int|list|tuple): The pool kernel size. If the kernel size is a tuple or list, it must contain three integers, (kernel_size_Depth, kernel_size_Height, kernel_size_Width). Otherwise, the pool kernel size will be the cube of an int. stride (int|list|tuple): The pool stride size. 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. padding (string|int|list|tuple): The padding size. Padding could be in one of the following forms. 1. A string in ['valid', 'same']. 2. An int, which means the feature map is zero padded by size of `padding` on every sides. 3. A list[int] or tuple(int) whose length is 3, [pad_depth, pad_height, pad_weight] whose value means the padding size of each dimension. 4. A list[int] or tuple(int) whose length is 6. [pad_depth_front, pad_depth_back, pad_height_top, pad_height_bottom, pad_width_left, pad_width_right] whose value means the padding size of each side. 5. A list or tuple of pairs of integers. It has the form [[pad_before, pad_after], [pad_before, pad_after], ...]. Note that, the batch dimension and channel dimension should be [0,0] or (0,0). The default value is 0. ceil_mode (bool): ${ceil_mode_comment} 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]`. Currently only support `"NDHWC"` . name(str, optional): For detailed information, please refer to :ref:`api_guide_Name`. Usually name is no need to set and None by default. Returns: Tensor: The output tensor of pooling result. The data type is same as input tensor. Examples: .. code-block:: python import paddle from paddle.fluid.framework import _test_eager_guard with _test_eager_guard(): dense_x = paddle.randn((1, 4, 4, 4, 3)) sparse_x = dense_x.to_sparse_coo(4) kernel_sizes = [3, 3, 3] paddings = [0, 0, 0] strides = [1, 1, 1] out = paddle.incubate.sparse.nn.functional.max_pool3d(sparse_x, kernel_sizes, stride=strides, padding=paddings) #[1, 2, 2, 2, 3] """ assert in_dynamic_mode(), "Currently, Sparse API only support dynamic mode" assert x.is_sparse_coo( ), "Currently, sparse.relu only support the input of SparseCooTensor" assert data_format == 'NDHWC', "Currently, sparse.max_pool3d only support data format of 'NDHWC'" kernel_size = utils.convert_to_list(kernel_size, 3, 'pool_size') if stride is None: stride = kernel_size else: stride = utils.convert_to_list(stride, 3, 'pool_stride') channel_last = True padding, padding_algorithm = _update_padding_nd(padding, 3, channel_last=channel_last, ceil_mode=ceil_mode) #TODO(zkh2016): remove the dependency on dilation from the backend dilation = [1, 1, 1] return _C_ops.final_state_sparse_maxpool(x, kernel_size, padding, dilation, stride)
def FConv2D(input, weight, bias=None, padding=0, stride=1, dilation=1, groups=1, use_cudnn=True, act=None, data_format="NCHW", name=None): # entry checks if not isinstance(use_cudnn, bool): raise ValueError("Attr(use_cudnn) should be True or False. " "Received Attr(use_cudnn): {}.".format(use_cudnn)) if data_format not in ["NCHW", "NHWC"]: raise ValueError("Attr(data_format) should be 'NCHW' or 'NHWC'. " "Received Attr(data_format): {}.".format(data_format)) channel_last = (data_format == "NHWC") channel_dim = -1 if channel_last else 1 num_channels = input.shape[channel_dim] num_filters = weight.shape[0] if num_channels < 0: raise ValueError("The channel dimmention of the input({}) " "should be defined. Received: {}.".format( input.shape, num_channels)) 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 {}" ", the groups is {}".format(num_channels, input.shape, groups)) if num_filters % groups != 0: raise ValueError( "the number of filters must be divisible by groups," "received: the number of filters is {}, the shape of weight is {}" ", the groups is {}".format(num_filters, weight.shape, groups)) # update attrs padding, padding_algorithm = _update_padding_nd(padding, channel_last, 2) stride = utils.convert_to_list(stride, 2, 'stride') dilation = utils.convert_to_list(dilation, 2, 'dilation') l_type = "conv2d" if (num_channels == groups and num_filters % num_channels == 0 and not use_cudnn): l_type = 'depthwise_conv2d' inputs = {'Input': [input], 'Filter': [weight]} 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 } if in_dygraph_mode(): 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) pre_bias = getattr(core.ops, l_type)(input, weight, *attrs) if bias is not None: pre_act = nn.elementwise_add(pre_bias, bias, axis=channel_dim) else: pre_act = pre_bias out = dygraph_utils._append_activation_in_dygraph( pre_act, act, use_cudnn=use_cudnn) else: inputs = {'Input': [input], 'Filter': [weight]} 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 } check_variable_and_dtype(input, 'input', ['float16', 'float32', 'float64'], 'conv2d') helper = LayerHelper(l_type, **locals()) dtype = helper.input_dtype() pre_bias = helper.create_variable_for_type_inference(dtype) outputs = {"Output": [pre_bias]} helper.append_op( type=l_type, inputs=inputs, outputs=outputs, attrs=attrs) if bias is not None: pre_act = nn.elementwise_add(pre_bias, bias, axis=channel_dim) else: pre_act = pre_bias out = helper.append_activation(pre_act) return out
def deformable_conv(input, offset, mask, num_filters, filter_size, stride=1, padding=0, dilation=1, groups=None, deformable_groups=None, im2col_step=None, filter_param=None, bias_attr=None, modulated=True, name=None): check_variable_and_dtype(input, "input", ['float32', 'float64'], 'deformable_conv') check_variable_and_dtype(offset, "offset", ['float32', 'float64'], 'deformable_conv') check_type(mask, 'mask', (Variable, type(None)), 'deformable_conv') num_channels = input.shape[1] assert filter_param is not None, "filter_param should not be None here." helper = LayerHelper('deformable_conv', **locals()) dtype = helper.input_dtype() if not isinstance(input, Variable): raise TypeError("Input of deformable_conv must be Variable") if not isinstance(offset, Variable): raise TypeError("Input Offset of deformable_conv must be Variable") if groups is None: num_filter_channels = num_channels else: if num_channels % groups != 0: raise ValueError("num_channels must be divisible by groups.") num_filter_channels = num_channels // groups filter_size = utils.convert_to_list(filter_size, 2, 'filter_size') stride = utils.convert_to_list(stride, 2, 'stride') padding = utils.convert_to_list(padding, 2, 'padding') dilation = utils.convert_to_list(dilation, 2, 'dilation') input_shape = input.shape filter_shape = [num_filters, int(num_filter_channels)] + filter_size def _get_default_param_initializer(): filter_elem_num = filter_size[0] * filter_size[1] * num_channels std = (2.0 / filter_elem_num)**0.5 return Normal(0.0, std, 0) pre_bias = helper.create_variable_for_type_inference(dtype) if modulated: helper.append_op(type='deformable_conv', inputs={ 'Input': input, 'Filter': filter_param, 'Offset': offset, 'Mask': mask, }, outputs={"Output": pre_bias}, attrs={ 'strides': stride, 'paddings': padding, 'dilations': dilation, 'groups': groups, 'deformable_groups': deformable_groups, 'im2col_step': im2col_step, }) else: helper.append_op(type='deformable_conv_v1', inputs={ 'Input': input, 'Filter': filter_param, 'Offset': offset, }, outputs={"Output": pre_bias}, attrs={ 'strides': stride, 'paddings': padding, 'dilations': dilation, 'groups': groups, 'deformable_groups': deformable_groups, 'im2col_step': im2col_step, }) output = helper.append_bias_op(pre_bias, dim_start=1, dim_end=2) return output
def Fconv2d(input, filter, stride=1, padding=0, dilation=1, groups=None, use_cudnn=True, name=None): """ 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=[3, 32, 32], \ dtype='float32') filter = fluid.data(name='filter',shape=[10,3,3,3], \ dtype='float32',append_batch_size=False) conv2d = fluid.layers.conv2d(input=data, filter=filter, act="relu") """ helper = LayerHelper("conv2d_with_filter", **locals()) num_channels = input.shape[1] num_filters = filter.shape[0] num_filter_channels = filter.shape[1] l_type = 'conv2d' # if (num_channels == groups and if (num_channels == groups and num_filters % num_channels == 0 and not use_cudnn): l_type = 'depthwise_conv2d' if groups is None: assert num_filter_channels == num_channels groups = 1 else: if num_channels % groups != 0: raise ValueError("num_channels must be divisible by groups.") if num_channels // groups != num_filter_channels: raise ValueError("num_filter_channels must equal to num_channels\ divided by groups.") stride = utils.convert_to_list(stride, 2, 'stride') padding = utils.convert_to_list(padding, 2, 'padding') dilation = utils.convert_to_list(dilation, 2, 'dilation') if not isinstance(use_cudnn, bool): raise ValueError("use_cudnn should be True or False") pre_bias = helper.create_variable_for_type_inference(dtype=input.dtype) helper.append_op(type=l_type, inputs={ 'Input': input, 'Filter': filter, }, outputs={"Output": pre_bias}, attrs={ 'strides': stride, 'paddings': padding, 'dilations': dilation, 'groups': groups, 'use_cudnn': use_cudnn, 'use_mkldnn': False }) return pre_bias