在 Pytorch 中实现 SeparableConv2D
Implement SeparableConv2D in Pytorch
主要objective
SeparableConv2D 的 PyTorch 等价物 padding = 'same'
:
from tensorflow.keras.layers import SeparableConv2D
x = SeparableConv2D(64, (1, 16), use_bias = False, padding = 'same')(x)
SeparableConv2D 的 PyTorch 等价物是什么?
这个source说:
If groups = nInputPlane, kernel=(K, 1), (and before is a Conv2d layer with groups=1 and kernel=(1, K)), then it is separable.
虽然这个 source 说:
Its core idea is to break down a complete convolutional acid into a two-step calculation, Depthwise Convolution and Pointwise.
这是我的尝试:
class SeparableConv2d(nn.Module):
def __init__(self, in_channels, out_channels, depth, kernel_size, bias=False):
super(SeparableConv2d, self).__init__()
self.depthwise = nn.Conv2d(in_channels, out_channels*depth, kernel_size=kernel_size, groups=in_channels, bias=bias)
self.pointwise = nn.Conv2d(out_channels*depth, out_channels, kernel_size=1, bias=bias)
def forward(self, x):
out = self.depthwise(x)
out = self.pointwise(out)
return out
这是正确的吗?这是否等同于 tensorflow.keras.layers.SeparableConv2D
?
padding = 'same'
呢?
执行此操作时如何确保我的输入和输出大小相同?
我的尝试:
x = F.pad(x, (8, 7, 0, 0), )
因为内核大小是(1,16)
,所以我添加了左右填充,分别为8和7。这是实现 padding = 'same'
的正确方法(也是最佳方法)吗?我怎样才能把它放在我的 SeparableConv2d
class 中,并在给定输入数据维度大小的情况下即时计算?
一起
class SeparableConv2d(nn.Module):
def __init__(self, in_channels, out_channels, depth, kernel_size, bias=False):
super(SeparableConv2d, self).__init__()
self.depthwise = nn.Conv2d(in_channels, out_channels*depth, kernel_size=kernel_size, groups=in_channels, bias=bias)
self.pointwise = nn.Conv2d(out_channels*depth, out_channels, kernel_size=1, bias=bias)
def forward(self, x):
out = self.depthwise(x)
out = self.pointwise(out)
return out
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.separable_conv = SeparableConv2d(
in_channels=32,
out_channels=64,
depth=1,
kernel_size=(1,16)
)
def forward(self, x):
x = F.pad(x, (8, 7, 0, 0), )
x = self.separable_conv(x)
return x
这些代码有问题吗?
链接的定义大体一致。最好的一个在 article.
- “Depthwise”(不是一个非常直观的名称,因为不涉及深度)- 是一系列规则的二维卷积,仅分别应用于数据层。 - "Pointwise" 与具有 1x1 内核的
Conv2d
相同。
我建议对您的 SeparableConv2d
进行一些更正 class:
- 无需使用深度参数 - 与 out_channels
相同
- 我将填充设置为 1 以确保与
kernel=(3,3)
相同的输出大小。如果内核大小不同 - 使用与常规 Conv2d 相同的原则相应地调整填充。您的示例 class Net()
不再需要 - 填充在 SeparableConv2d
. 中完成
这是更新后的代码,应该类似于tf.keras.layers.SeparableConv2D
实现:
class SeparableConv2d(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size, bias=False):
super(SeparableConv2d, self).__init__()
self.depthwise = nn.Conv2d(in_channels, in_channels, kernel_size=kernel_size,
groups=in_channels, bias=bias, padding=1)
self.pointwise = nn.Conv2d(in_channels, out_channels,
kernel_size=1, bias=bias)
def forward(self, x):
out = self.depthwise(x)
out = self.pointwise(out)
return out
主要objective
SeparableConv2D 的 PyTorch 等价物 padding = 'same'
:
from tensorflow.keras.layers import SeparableConv2D
x = SeparableConv2D(64, (1, 16), use_bias = False, padding = 'same')(x)
SeparableConv2D 的 PyTorch 等价物是什么?
这个source说:
If groups = nInputPlane, kernel=(K, 1), (and before is a Conv2d layer with groups=1 and kernel=(1, K)), then it is separable.
虽然这个 source 说:
Its core idea is to break down a complete convolutional acid into a two-step calculation, Depthwise Convolution and Pointwise.
这是我的尝试:
class SeparableConv2d(nn.Module):
def __init__(self, in_channels, out_channels, depth, kernel_size, bias=False):
super(SeparableConv2d, self).__init__()
self.depthwise = nn.Conv2d(in_channels, out_channels*depth, kernel_size=kernel_size, groups=in_channels, bias=bias)
self.pointwise = nn.Conv2d(out_channels*depth, out_channels, kernel_size=1, bias=bias)
def forward(self, x):
out = self.depthwise(x)
out = self.pointwise(out)
return out
这是正确的吗?这是否等同于 tensorflow.keras.layers.SeparableConv2D
?
padding = 'same'
呢?
执行此操作时如何确保我的输入和输出大小相同?
我的尝试:
x = F.pad(x, (8, 7, 0, 0), )
因为内核大小是(1,16)
,所以我添加了左右填充,分别为8和7。这是实现 padding = 'same'
的正确方法(也是最佳方法)吗?我怎样才能把它放在我的 SeparableConv2d
class 中,并在给定输入数据维度大小的情况下即时计算?
一起
class SeparableConv2d(nn.Module):
def __init__(self, in_channels, out_channels, depth, kernel_size, bias=False):
super(SeparableConv2d, self).__init__()
self.depthwise = nn.Conv2d(in_channels, out_channels*depth, kernel_size=kernel_size, groups=in_channels, bias=bias)
self.pointwise = nn.Conv2d(out_channels*depth, out_channels, kernel_size=1, bias=bias)
def forward(self, x):
out = self.depthwise(x)
out = self.pointwise(out)
return out
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.separable_conv = SeparableConv2d(
in_channels=32,
out_channels=64,
depth=1,
kernel_size=(1,16)
)
def forward(self, x):
x = F.pad(x, (8, 7, 0, 0), )
x = self.separable_conv(x)
return x
这些代码有问题吗?
链接的定义大体一致。最好的一个在 article.
- “Depthwise”(不是一个非常直观的名称,因为不涉及深度)- 是一系列规则的二维卷积,仅分别应用于数据层。 - "Pointwise" 与具有 1x1 内核的
Conv2d
相同。
我建议对您的 SeparableConv2d
进行一些更正 class:
- 无需使用深度参数 - 与 out_channels 相同
- 我将填充设置为 1 以确保与
kernel=(3,3)
相同的输出大小。如果内核大小不同 - 使用与常规 Conv2d 相同的原则相应地调整填充。您的示例 classNet()
不再需要 - 填充在SeparableConv2d
. 中完成
这是更新后的代码,应该类似于tf.keras.layers.SeparableConv2D
实现:
class SeparableConv2d(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size, bias=False):
super(SeparableConv2d, self).__init__()
self.depthwise = nn.Conv2d(in_channels, in_channels, kernel_size=kernel_size,
groups=in_channels, bias=bias, padding=1)
self.pointwise = nn.Conv2d(in_channels, out_channels,
kernel_size=1, bias=bias)
def forward(self, x):
out = self.depthwise(x)
out = self.pointwise(out)
return out