|
|
|
@@ -14,7 +14,7 @@ import numpy as np |
|
|
|
import megengine._internal as mgb |
|
|
|
|
|
|
|
from ..core import Parameter |
|
|
|
from ..functional import conv2d, conv_transpose2d |
|
|
|
from ..functional import conv2d, conv_transpose2d, local_conv2d |
|
|
|
from ..utils.types import _pair, _pair_nonzero |
|
|
|
from . import init |
|
|
|
from .module import Module |
|
|
|
@@ -224,7 +224,7 @@ class ConvTranspose2d(_ConvNd): |
|
|
|
``in_channels`` and ``out_channels`` must be divisible by ``groups``, |
|
|
|
and there would be an extra dimension at the beginning of the weight's |
|
|
|
shape. Specifically, the shape of weight would be ``(groups, |
|
|
|
out_channel // groups, in_channels // groups, *kernel_size)``. Default: 1 |
|
|
|
out_channels // groups, in_channels // groups, *kernel_size)``. Default: 1 |
|
|
|
:param bias: wether to add a bias onto the result of convolution. Default: |
|
|
|
True |
|
|
|
:param conv_mode: Supports `CROSS_CORRELATION` or `CONVOLUTION`. Default: |
|
|
|
@@ -306,3 +306,77 @@ class ConvTranspose2d(_ConvNd): |
|
|
|
self.conv_mode, |
|
|
|
self.compute_mode, |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
class LocalConv2d(Conv2d): |
|
|
|
r"""Applies a spatial convolution with untied kernels over an input 4D tensor. |
|
|
|
It is also known as the locally connected layer. |
|
|
|
|
|
|
|
:param in_channels: number of input channels. |
|
|
|
:param out_channels: number of output channels. |
|
|
|
:param input_height: the height of the input images. |
|
|
|
:param input_width: the width of the input images. |
|
|
|
:param kernel_size: size of weight on spatial dimensions. If ``kernel_size`` is |
|
|
|
an :class:`int`, the actual kernel size would be |
|
|
|
``(kernel_size, kernel_size)``. Default: 1 |
|
|
|
:param stride: stride of the 2D convolution operation. Default: 1 |
|
|
|
:param padding: size of the paddings added to the input on both sides of its |
|
|
|
spatial dimensions. Only zero-padding is supported. Default: 0 |
|
|
|
:param groups: number of groups to divide input and output channels into, |
|
|
|
so as to perform a "grouped convolution". When ``groups`` is not 1, |
|
|
|
``in_channels`` and ``out_channels`` must be divisible by ``groups``. |
|
|
|
The shape of weight is ``(groups, output_height, output_width, |
|
|
|
in_channels // groups, *kernel_size, out_channels // groups)``. |
|
|
|
""" |
|
|
|
|
|
|
|
_conv_mode_type = mgb.opr_param_defs.Convolution.Mode |
|
|
|
|
|
|
|
def __init__( |
|
|
|
self, |
|
|
|
in_channels: int, |
|
|
|
out_channels: int, |
|
|
|
input_height: int, |
|
|
|
input_width: int, |
|
|
|
kernel_size: Union[int, Tuple[int, int]], |
|
|
|
stride: Union[int, Tuple[int, int]] = 1, |
|
|
|
padding: Union[int, Tuple[int, int]] = 0, |
|
|
|
dilation: Union[int, Tuple[int, int]] = 1, |
|
|
|
groups: int = 1, |
|
|
|
conv_mode: str = "CROSS_CORRELATION", |
|
|
|
): |
|
|
|
self.input_height = input_height |
|
|
|
self.input_width = input_width |
|
|
|
super().__init__( |
|
|
|
in_channels, |
|
|
|
out_channels, |
|
|
|
kernel_size, |
|
|
|
stride, |
|
|
|
padding, |
|
|
|
dilation, |
|
|
|
groups, |
|
|
|
bias=False, |
|
|
|
) |
|
|
|
|
|
|
|
def _infer_weight_shape(self): |
|
|
|
group = self.groups |
|
|
|
output_height = ( |
|
|
|
self.input_height + self.padding[0] * 2 - self.kernel_size[0] |
|
|
|
) // self.stride[0] + 1 |
|
|
|
output_width = ( |
|
|
|
self.input_width + self.padding[1] * 2 - self.kernel_size[1] |
|
|
|
) // self.stride[1] + 1 |
|
|
|
# Assume format is NCHW |
|
|
|
return ( |
|
|
|
group, |
|
|
|
output_height, |
|
|
|
output_width, |
|
|
|
self.in_channels // group, |
|
|
|
self.kernel_size[0], |
|
|
|
self.kernel_size[1], |
|
|
|
self.out_channels // group, |
|
|
|
) |
|
|
|
|
|
|
|
def forward(self, inp): |
|
|
|
return local_conv2d( |
|
|
|
inp, self.weight, self.stride, self.padding, self.dilation, self.conv_mode |
|
|
|
) |