707 lines
23 KiB
Python
707 lines
23 KiB
Python
# Copyright (c) 2022 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.
|
|
|
|
import numpy as np
|
|
|
|
import paddle
|
|
from paddle import _legacy_C_ops, base
|
|
from paddle.base.layer_helper import LayerHelper
|
|
from paddle.base.param_attr import ParamAttr
|
|
from paddle.nn import (
|
|
Layer,
|
|
initializer as I,
|
|
)
|
|
|
|
__all__ = ['resnet_basic_block', 'ResNetBasicBlock']
|
|
|
|
|
|
def resnet_basic_block(
|
|
x,
|
|
filter1,
|
|
scale1,
|
|
bias1,
|
|
mean1,
|
|
var1,
|
|
filter2,
|
|
scale2,
|
|
bias2,
|
|
mean2,
|
|
var2,
|
|
filter3,
|
|
scale3,
|
|
bias3,
|
|
mean3,
|
|
var3,
|
|
stride1,
|
|
stride2,
|
|
stride3,
|
|
padding1,
|
|
padding2,
|
|
padding3,
|
|
dilation1,
|
|
dilation2,
|
|
dilation3,
|
|
groups,
|
|
momentum,
|
|
eps,
|
|
data_format,
|
|
has_shortcut,
|
|
use_global_stats=None,
|
|
training=False,
|
|
trainable_statistics=False,
|
|
find_conv_max=True,
|
|
):
|
|
if base.framework.in_dygraph_mode():
|
|
attrs = (
|
|
'stride1',
|
|
stride1,
|
|
'stride2',
|
|
stride2,
|
|
'stride3',
|
|
stride3,
|
|
'padding1',
|
|
padding1,
|
|
'padding2',
|
|
padding2,
|
|
'padding3',
|
|
padding3,
|
|
'dilation1',
|
|
dilation1,
|
|
'dilation2',
|
|
dilation2,
|
|
'dilation3',
|
|
dilation3,
|
|
'group',
|
|
groups,
|
|
'momentum',
|
|
momentum,
|
|
'epsilon',
|
|
eps,
|
|
'data_format',
|
|
data_format,
|
|
'has_shortcut',
|
|
has_shortcut,
|
|
'use_global_stats',
|
|
use_global_stats,
|
|
"trainable_statistics",
|
|
trainable_statistics,
|
|
'is_test',
|
|
not training,
|
|
'act_type',
|
|
"relu",
|
|
'find_conv_input_max',
|
|
find_conv_max,
|
|
)
|
|
|
|
(
|
|
out,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
) = _legacy_C_ops.resnet_basic_block(
|
|
x,
|
|
filter1,
|
|
scale1,
|
|
bias1,
|
|
mean1,
|
|
var1,
|
|
filter2,
|
|
scale2,
|
|
bias2,
|
|
mean2,
|
|
var2,
|
|
filter3,
|
|
scale3,
|
|
bias3,
|
|
mean3,
|
|
var3,
|
|
mean1,
|
|
var1,
|
|
mean2,
|
|
var2,
|
|
mean3,
|
|
var3,
|
|
*attrs,
|
|
)
|
|
return out
|
|
helper = LayerHelper('resnet_basic_block', **locals())
|
|
bn_param_dtype = base.core.VarDesc.VarType.FP32
|
|
max_dtype = base.core.VarDesc.VarType.FP32
|
|
|
|
out = helper.create_variable_for_type_inference(
|
|
dtype=x.dtype, stop_gradient=True
|
|
)
|
|
conv1 = helper.create_variable_for_type_inference(
|
|
dtype=x.dtype, stop_gradient=True
|
|
)
|
|
saved_mean1 = helper.create_variable_for_type_inference(
|
|
dtype=bn_param_dtype, stop_gradient=True
|
|
)
|
|
saved_invstd1 = helper.create_variable_for_type_inference(
|
|
dtype=bn_param_dtype, stop_gradient=True
|
|
)
|
|
running_mean1 = (
|
|
helper.create_variable_for_type_inference(
|
|
dtype=bn_param_dtype, stop_gradient=True
|
|
)
|
|
if mean1 is None
|
|
else mean1
|
|
)
|
|
running_var1 = (
|
|
helper.create_variable_for_type_inference(
|
|
dtype=bn_param_dtype, stop_gradient=True
|
|
)
|
|
if var1 is None
|
|
else var1
|
|
)
|
|
conv2 = helper.create_variable_for_type_inference(
|
|
dtype=x.dtype, stop_gradient=True
|
|
)
|
|
conv2_input = helper.create_variable_for_type_inference(
|
|
dtype=x.dtype, stop_gradient=True
|
|
)
|
|
saved_mean2 = helper.create_variable_for_type_inference(
|
|
dtype=bn_param_dtype, stop_gradient=True
|
|
)
|
|
saved_invstd2 = helper.create_variable_for_type_inference(
|
|
dtype=bn_param_dtype, stop_gradient=True
|
|
)
|
|
running_mean2 = (
|
|
helper.create_variable_for_type_inference(
|
|
dtype=bn_param_dtype, stop_gradient=True
|
|
)
|
|
if mean2 is None
|
|
else mean2
|
|
)
|
|
running_var2 = (
|
|
helper.create_variable_for_type_inference(
|
|
dtype=bn_param_dtype, stop_gradient=True
|
|
)
|
|
if var2 is None
|
|
else var2
|
|
)
|
|
conv3 = helper.create_variable_for_type_inference(
|
|
dtype=x.dtype, stop_gradient=True
|
|
)
|
|
saved_mean3 = helper.create_variable_for_type_inference(
|
|
dtype=bn_param_dtype, stop_gradient=True
|
|
)
|
|
saved_invstd3 = helper.create_variable_for_type_inference(
|
|
dtype=bn_param_dtype, stop_gradient=True
|
|
)
|
|
running_mean3 = (
|
|
helper.create_variable_for_type_inference(
|
|
dtype=bn_param_dtype, stop_gradient=True
|
|
)
|
|
if mean3 is None
|
|
else mean3
|
|
)
|
|
running_var3 = (
|
|
helper.create_variable_for_type_inference(
|
|
dtype=bn_param_dtype, stop_gradient=True
|
|
)
|
|
if var3 is None
|
|
else var3
|
|
)
|
|
conv1_input_max = helper.create_variable_for_type_inference(
|
|
dtype=max_dtype, stop_gradient=True
|
|
)
|
|
conv1_filter_max = helper.create_variable_for_type_inference(
|
|
dtype=max_dtype, stop_gradient=True
|
|
)
|
|
conv2_input_max = helper.create_variable_for_type_inference(
|
|
dtype=max_dtype, stop_gradient=True
|
|
)
|
|
conv2_filter_max = helper.create_variable_for_type_inference(
|
|
dtype=max_dtype, stop_gradient=True
|
|
)
|
|
conv3_input_max = helper.create_variable_for_type_inference(
|
|
dtype=max_dtype, stop_gradient=True
|
|
)
|
|
conv3_filter_max = helper.create_variable_for_type_inference(
|
|
dtype=max_dtype, stop_gradient=True
|
|
)
|
|
|
|
inputs = {
|
|
'X': x,
|
|
'Filter1': filter1,
|
|
'Scale1': scale1,
|
|
'Bias1': bias1,
|
|
'Mean1': mean1,
|
|
'Var1': var1,
|
|
'Filter2': filter2,
|
|
'Scale2': scale2,
|
|
'Bias2': bias2,
|
|
'Mean2': mean2,
|
|
'Var2': var2,
|
|
'Filter3': filter3,
|
|
'Scale3': scale3,
|
|
'Bias3': bias3,
|
|
'Mean3': mean3,
|
|
'Var3': var3,
|
|
}
|
|
|
|
attrs = {
|
|
'stride1': stride1,
|
|
'stride2': stride2,
|
|
'stride3': stride3,
|
|
'padding1': padding1,
|
|
'padding2': padding2,
|
|
'padding3': padding3,
|
|
'dilation1': dilation1,
|
|
'dilation2': dilation2,
|
|
'dilation3': dilation3,
|
|
'group': groups,
|
|
'momentum': momentum,
|
|
'epsilon': eps,
|
|
'data_format': data_format,
|
|
'has_shortcut': has_shortcut,
|
|
'use_global_stats': use_global_stats,
|
|
"trainable_statistics": trainable_statistics,
|
|
'is_test': not training,
|
|
'act_type': "relu",
|
|
'find_conv_input_max': find_conv_max,
|
|
}
|
|
|
|
outputs = {
|
|
'Y': out,
|
|
'Conv1': conv1,
|
|
'SavedMean1': saved_mean1,
|
|
'SavedInvstd1': saved_invstd1,
|
|
'Mean1Out': running_mean1,
|
|
'Var1Out': running_var1,
|
|
'Conv2': conv2,
|
|
'SavedMean2': saved_mean2,
|
|
'SavedInvstd2': saved_invstd2,
|
|
'Mean2Out': running_mean2,
|
|
'Var2Out': running_var2,
|
|
'Conv2Input': conv2_input,
|
|
'Conv3': conv3,
|
|
'SavedMean3': saved_mean3,
|
|
'SavedInvstd3': saved_invstd3,
|
|
'Mean3Out': running_mean3,
|
|
'Var3Out': running_var3,
|
|
'MaxInput1': conv1_input_max,
|
|
'MaxFilter1': conv1_filter_max,
|
|
'MaxInput2': conv2_input_max,
|
|
'MaxFilter2': conv2_filter_max,
|
|
'MaxInput3': conv3_input_max,
|
|
'MaxFilter3': conv3_filter_max,
|
|
}
|
|
helper.append_op(
|
|
type='resnet_basic_block', inputs=inputs, outputs=outputs, attrs=attrs
|
|
)
|
|
return out
|
|
|
|
|
|
class ResNetBasicBlock(Layer):
|
|
r"""
|
|
|
|
ResNetBasicBlock is designed for optimize the performance of the basic unit of ssd resnet block.
|
|
If has_shortcut = True, it can calculate 3 Conv2D, 3 BatchNorm and 2 ReLU in one time.
|
|
If has_shortcut = False, it can calculate 2 Conv2D, 2 BatchNorm and 2 ReLU in one time. In this
|
|
case the shape of output is same with input.
|
|
|
|
|
|
Args:
|
|
num_channels (int): The number of input image channel.
|
|
num_filter (int): The number of filter. It is as same as the output image channel.
|
|
filter_size (int|list|tuple): The filter size. If filter_size
|
|
is a tuple, it must contain two integers, (filter_size_height,
|
|
filter_size_width). Otherwise, filter_size_height = filter_size_width =\
|
|
filter_size.
|
|
stride (int, optional): The stride size. It means the stride in convolution.
|
|
If stride is a tuple, it must contain two integers, (stride_height, stride_width).
|
|
Otherwise, stride_height = stride_width = stride. Default: stride = 1.
|
|
act (str, optional): Activation type, if it is set to None, activation is not appended.
|
|
Default: None
|
|
momentum (float, optional): The value used for the moving_mean and
|
|
moving_var computation. This should be a float number or a 0-D Tensor with
|
|
shape [] and data type as float32. The updated formula is:
|
|
:math:`moving\_mean = moving\_mean * momentum + new\_mean * (1. - momentum)`
|
|
:math:`moving\_var = moving\_var * momentum + new\_var * (1. - momentum)`
|
|
Default is 0.9.
|
|
eps (float, optional): A value added to the denominator for
|
|
numerical stability. Default is 1e-5.
|
|
data_format (str, optional): Specify the data format of the input, and the data format of the output
|
|
will be consistent with that of the input. Now is only support `"NCHW"`, the data is stored in
|
|
the order of: `[batch_size, input_channels, input_height, input_width]`.
|
|
has_shortcut (bool, optional): Whether to calculate CONV3 and BN3. Default: False.
|
|
use_global_stats (bool, optional): 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. Default: False.
|
|
is_test (bool, optional): A flag indicating whether it is in
|
|
test phrase or not. Default: False.
|
|
filter_attr (ParamAttr, optional): 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. Default: None.
|
|
scale_attr (ParamAttr, optional): The parameter attribute for Parameter `scale`
|
|
of batch_norm. If it is set to None or one attribute of ParamAttr, batch_norm will create ParamAttr
|
|
as param_attr, the name of scale can be set in ParamAttr. If the Initializer of the param_attr is not set,
|
|
the parameter is initialized with Xavier. Default: None.
|
|
bias_attr (ParamAttr, optional): The parameter attribute for the bias of batch_norm.
|
|
If it is set to None or one attribute of ParamAttr, batch_norm
|
|
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.
|
|
Default: None.
|
|
moving_mean_name (str, optional): 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
|
|
will save global mean with the string. Default: None.
|
|
moving_var_name (str, optional): The name of the moving_variance which store the global Variance.
|
|
If it is set to None, batch_norm will save global variance with a random name, otherwise, batch_norm
|
|
will save global variance with the string. Default: None.
|
|
padding (int, optional): The padding size. It is only support padding_height = padding_width = padding.
|
|
Default: padding = 0.
|
|
dilation (int, optional): The dilation size. It means the spacing between the kernel
|
|
points. It is only support dilation_height = dilation_width = dilation.
|
|
Default: dilation = 1.
|
|
trainable_statistics (bool, optional): Whether to calculate mean and var in eval mode. In eval mode, when
|
|
setting trainable_statistics True, mean and variance will be calculated by current batch statistics.
|
|
Default: False.
|
|
find_conv_max (bool, optional): Whether to calculate max value of each conv2d. Default: True.
|
|
|
|
|
|
Returns:
|
|
A Tensor representing the ResNetBasicBlock, whose data type is the same with input.
|
|
|
|
|
|
Examples:
|
|
.. code-block:: pycon
|
|
|
|
>>> # doctest: +REQUIRES(env: XPU)
|
|
>>> import paddle
|
|
>>> from paddle.incubate.xpu.resnet_block import ResNetBasicBlock
|
|
|
|
>>> ch_in = 4
|
|
>>> ch_out = 8
|
|
>>> x = paddle.uniform((2, ch_in, 16, 16), dtype='float32', min=-1., max=1.)
|
|
>>> resnet_basic_block = ResNetBasicBlock(num_channels1=ch_in,
|
|
... num_filter1=ch_out,
|
|
... filter1_size=3,
|
|
... num_channels2=ch_out,
|
|
... num_filter2=ch_out,
|
|
... filter2_size=3,
|
|
... num_channels3=ch_in,
|
|
... num_filter3=ch_out,
|
|
... filter3_size=1,
|
|
... stride1=1,
|
|
... stride2=1,
|
|
... stride3=1,
|
|
... act='relu',
|
|
... padding1=1,
|
|
... padding2=1,
|
|
... padding3=0,
|
|
... has_shortcut=True)
|
|
>>> out = resnet_basic_block.forward(x)
|
|
|
|
>>> print(out.shape)
|
|
paddle.Size([2, 8, 16, 16])
|
|
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
num_channels1,
|
|
num_filter1,
|
|
filter1_size,
|
|
num_channels2,
|
|
num_filter2,
|
|
filter2_size,
|
|
num_channels3,
|
|
num_filter3,
|
|
filter3_size,
|
|
stride1=1,
|
|
stride2=1,
|
|
stride3=1,
|
|
act='relu',
|
|
momentum=0.9,
|
|
eps=1e-5,
|
|
data_format='NCHW',
|
|
has_shortcut=False,
|
|
use_global_stats=False,
|
|
is_test=False,
|
|
filter1_attr=None,
|
|
scale1_attr=None,
|
|
bias1_attr=None,
|
|
moving_mean1_name=None,
|
|
moving_var1_name=None,
|
|
filter2_attr=None,
|
|
scale2_attr=None,
|
|
bias2_attr=None,
|
|
moving_mean2_name=None,
|
|
moving_var2_name=None,
|
|
filter3_attr=None,
|
|
scale3_attr=None,
|
|
bias3_attr=None,
|
|
moving_mean3_name=None,
|
|
moving_var3_name=None,
|
|
padding1=0,
|
|
padding2=0,
|
|
padding3=0,
|
|
dilation1=1,
|
|
dilation2=1,
|
|
dilation3=1,
|
|
trainable_statistics=False,
|
|
find_conv_max=True,
|
|
):
|
|
super().__init__()
|
|
self._stride1 = stride1
|
|
self._stride2 = stride2
|
|
self._kernel1_size = paddle.utils.convert_to_list(
|
|
filter1_size, 2, 'filter1_size'
|
|
)
|
|
self._kernel2_size = paddle.utils.convert_to_list(
|
|
filter2_size, 2, 'filter2_size'
|
|
)
|
|
self._dilation1 = dilation1
|
|
self._dilation2 = dilation2
|
|
self._padding1 = padding1
|
|
self._padding2 = padding2
|
|
self._groups = 1
|
|
self._momentum = momentum
|
|
self._eps = eps
|
|
self._data_format = data_format
|
|
self._act = act
|
|
self._has_shortcut = has_shortcut
|
|
self._use_global_stats = use_global_stats
|
|
self._is_test = is_test
|
|
self._trainable_statistics = trainable_statistics
|
|
self._find_conv_max = find_conv_max
|
|
|
|
if has_shortcut:
|
|
self._kernel3_size = paddle.utils.convert_to_list(
|
|
filter3_size, 2, 'filter3_size'
|
|
)
|
|
self._padding3 = padding3
|
|
self._stride3 = stride3
|
|
self._dilation3 = dilation3
|
|
else:
|
|
self._kernel3_size = None
|
|
self._padding3 = 1
|
|
self._stride3 = 1
|
|
self._dilation3 = 1
|
|
|
|
# check format
|
|
valid_format = {'NCHW'}
|
|
if data_format not in valid_format:
|
|
raise ValueError(
|
|
f"conv_format must be one of {valid_format}, but got conv_format={data_format}"
|
|
)
|
|
|
|
def _get_default_param_initializer(channels, kernel_size):
|
|
filter_elem_num = np.prod(kernel_size) * channels
|
|
std = (2.0 / filter_elem_num) ** 0.5
|
|
return I.Normal(0.0, std)
|
|
|
|
# init filter
|
|
bn_param_dtype = base.core.VarDesc.VarType.FP32
|
|
bn1_param_shape = [1, 1, num_filter1]
|
|
bn2_param_shape = [1, 1, num_filter2]
|
|
filter1_shape = [num_filter1, num_channels1, filter1_size, filter1_size]
|
|
filter2_shape = [num_filter2, num_channels2, filter2_size, filter2_size]
|
|
|
|
self.filter_1 = self.create_parameter(
|
|
shape=filter1_shape,
|
|
attr=filter1_attr,
|
|
default_initializer=_get_default_param_initializer(
|
|
num_channels1, self._kernel1_size
|
|
),
|
|
)
|
|
self.scale_1 = self.create_parameter(
|
|
shape=bn1_param_shape,
|
|
attr=scale1_attr,
|
|
dtype=bn_param_dtype,
|
|
default_initializer=I.Constant(1.0),
|
|
)
|
|
self.bias_1 = self.create_parameter(
|
|
shape=bn1_param_shape,
|
|
attr=bias1_attr,
|
|
dtype=bn_param_dtype,
|
|
is_bias=True,
|
|
)
|
|
self.mean_1 = self.create_parameter(
|
|
attr=ParamAttr(
|
|
name=moving_mean1_name,
|
|
initializer=I.Constant(0.0),
|
|
trainable=False,
|
|
),
|
|
shape=bn1_param_shape,
|
|
dtype=bn_param_dtype,
|
|
)
|
|
self.mean_1.stop_gradient = True
|
|
self.var_1 = self.create_parameter(
|
|
attr=ParamAttr(
|
|
name=moving_var1_name,
|
|
initializer=I.Constant(1.0),
|
|
trainable=False,
|
|
),
|
|
shape=bn1_param_shape,
|
|
dtype=bn_param_dtype,
|
|
)
|
|
self.var_1.stop_gradient = True
|
|
|
|
self.filter_2 = self.create_parameter(
|
|
shape=filter2_shape,
|
|
attr=filter2_attr,
|
|
default_initializer=_get_default_param_initializer(
|
|
num_channels2, self._kernel2_size
|
|
),
|
|
)
|
|
self.scale_2 = self.create_parameter(
|
|
shape=bn2_param_shape,
|
|
attr=scale2_attr,
|
|
dtype=bn_param_dtype,
|
|
default_initializer=I.Constant(1.0),
|
|
)
|
|
self.bias_2 = self.create_parameter(
|
|
shape=bn2_param_shape,
|
|
attr=bias2_attr,
|
|
dtype=bn_param_dtype,
|
|
is_bias=True,
|
|
)
|
|
self.mean_2 = self.create_parameter(
|
|
attr=ParamAttr(
|
|
name=moving_mean2_name,
|
|
initializer=I.Constant(0.0),
|
|
trainable=False,
|
|
),
|
|
shape=bn2_param_shape,
|
|
dtype=bn_param_dtype,
|
|
)
|
|
self.mean_2.stop_gradient = True
|
|
self.var_2 = self.create_parameter(
|
|
attr=ParamAttr(
|
|
name=moving_var2_name,
|
|
initializer=I.Constant(1.0),
|
|
trainable=False,
|
|
),
|
|
shape=bn2_param_shape,
|
|
dtype=bn_param_dtype,
|
|
)
|
|
self.var_2.stop_gradient = True
|
|
|
|
if has_shortcut:
|
|
bn3_param_shape = [1, 1, num_filter3]
|
|
filter3_shape = [
|
|
num_filter3,
|
|
num_channels3,
|
|
filter3_size,
|
|
filter3_size,
|
|
]
|
|
self.filter_3 = self.create_parameter(
|
|
shape=filter3_shape,
|
|
attr=filter3_attr,
|
|
default_initializer=_get_default_param_initializer(
|
|
num_channels3, self._kernel3_size
|
|
),
|
|
)
|
|
self.scale_3 = self.create_parameter(
|
|
shape=bn3_param_shape,
|
|
attr=scale3_attr,
|
|
dtype=bn_param_dtype,
|
|
default_initializer=I.Constant(1.0),
|
|
)
|
|
self.bias_3 = self.create_parameter(
|
|
shape=bn3_param_shape,
|
|
attr=bias3_attr,
|
|
dtype=bn_param_dtype,
|
|
is_bias=True,
|
|
)
|
|
self.mean_3 = self.create_parameter(
|
|
attr=ParamAttr(
|
|
name=moving_mean3_name,
|
|
initializer=I.Constant(0.0),
|
|
trainable=False,
|
|
),
|
|
shape=bn3_param_shape,
|
|
dtype=bn_param_dtype,
|
|
)
|
|
self.mean_3.stop_gradient = True
|
|
self.var_3 = self.create_parameter(
|
|
attr=ParamAttr(
|
|
name=moving_var3_name,
|
|
initializer=I.Constant(1.0),
|
|
trainable=False,
|
|
),
|
|
shape=bn3_param_shape,
|
|
dtype=bn_param_dtype,
|
|
)
|
|
self.var_3.stop_gradient = True
|
|
else:
|
|
self.filter_3 = None
|
|
self.scale_3 = None
|
|
self.bias_3 = None
|
|
self.mean_3 = None
|
|
self.var_3 = None
|
|
|
|
def forward(self, x):
|
|
out = resnet_basic_block(
|
|
x,
|
|
self.filter_1,
|
|
self.scale_1,
|
|
self.bias_1,
|
|
self.mean_1,
|
|
self.var_1,
|
|
self.filter_2,
|
|
self.scale_2,
|
|
self.bias_2,
|
|
self.mean_2,
|
|
self.var_2,
|
|
self.filter_3,
|
|
self.scale_3,
|
|
self.bias_3,
|
|
self.mean_3,
|
|
self.var_3,
|
|
self._stride1,
|
|
self._stride2,
|
|
self._stride3,
|
|
self._padding1,
|
|
self._padding2,
|
|
self._padding3,
|
|
self._dilation1,
|
|
self._dilation2,
|
|
self._dilation3,
|
|
self._groups,
|
|
self._momentum,
|
|
self._eps,
|
|
self._data_format,
|
|
self._has_shortcut,
|
|
use_global_stats=self._use_global_stats,
|
|
training=self.training,
|
|
trainable_statistics=self._trainable_statistics,
|
|
find_conv_max=self._find_conv_max,
|
|
)
|
|
return out
|