目录
- 浅析Pytorch中的Padding策略
- 浅析Tensorflow中的Padding策略
- 代码实现
1. 浅析Pytorch中的Padding策略
时机:padding是在卷积之前补0的
默认策略:四周都补!如果padding参数传入的是一个tuple的话,第一个参数表示高度上面的padding,第二个参数表示宽度上的padding
import torch
import torch.nn as nn
t = torch.ones(1,1,5,5)
conv = nn.Conv2d(in_channels=1, out_channels=1,
kernel_size=(1,1), padding=1, bias=True)
print(t)
print(conv(t))
程序输出如下(在这个例子里,卷积的weight为0.7481,bias为0.4789)
tensor([[[[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]]]])
tensor([[[[0.4789, 0.4789, 0.4789, 0.4789, 0.4789, 0.4789, 0.4789],
[0.4789, 1.2270, 1.2270, 1.2270, 1.2270, 1.2270, 0.4789],
[0.4789, 1.2270, 1.2270, 1.2270, 1.2270, 1.2270, 0.4789],
[0.4789, 1.2270, 1.2270, 1.2270, 1.2270, 1.2270, 0.4789],
[0.4789, 1.2270, 1.2270, 1.2270, 1.2270, 1.2270, 0.4789],
[0.4789, 1.2270, 1.2270, 1.2270, 1.2270, 1.2270, 0.4789],
[0.4789, 0.4789, 0.4789, 0.4789, 0.4789, 0.4789, 0.4789]]]],
grad_fn=<ThnnConv2DBackward>)
2. 浅析Tensorflow中的Padding策略
Tensorflow中的Padding模式分为两种,分别为SAME
和VALID
stackoverflow中有个回答很直观就能解释这两者的区别

划重点:
VALID
: only ever drops the right-most columns (or bottom-most rows).SAME
: tries to pad evenly left and right, but if the amount of columns to be added is odd, it will add the extra column to the right, as is the case in this example (the same logic applies vertically: there may be an extra row of zeros at the bottom).
3. 代码实现
import torch.utils.data
from torch.nn import functional as F
import math
import torch
from torch.nn.parameter import Parameter
from torch.nn.functional import pad
from torch.nn.modules import Module
from torch.nn.modules.utils import _single, _pair, _triple
class _ConvNd(Module):
def __init__(self, in_channels, out_channels, kernel_size, stride,
padding, dilation, transposed, output_padding, groups, bias):
super(_ConvNd, self).__init__()
if in_channels % groups != 0:
raise ValueError('in_channels must be divisible by groups')
if out_channels % groups != 0:
raise ValueError('out_channels must be divisible by groups')
self.in_channels = in_channels
self.out_channels = out_channels
self.kernel_size = kernel_size
self.stride = stride
self.padding = padding
self.dilation = dilation
self.transposed = transposed
self.output_padding = output_padding
self.groups = groups
if transposed:
self.weight = Parameter(torch.Tensor(
in_channels, out_channels // groups, *kernel_size))
else:
self.weight = Parameter(torch.Tensor(
out_channels, in_channels // groups, *kernel_size))
if bias:
self.bias = Parameter(torch.Tensor(out_channels))
else:
self.register_parameter('bias', None)
self.reset_parameters()
def reset_parameters(self):
n = self.in_channels
for k in self.kernel_size:
n *= k
stdv = 1. / math.sqrt(n)
self.weight.data.uniform_(-stdv, stdv)
if self.bias is not None:
self.bias.data.uniform_(-stdv, stdv)
def __repr__(self):
s = ('{name}({in_channels}, {out_channels}, kernel_size={kernel_size}'
', stride={stride}')
if self.padding != (0,) * len(self.padding):
s += ', padding={padding}'
if self.dilation != (1,) * len(self.dilation):
s += ', dilation={dilation}'
if self.output_padding != (0,) * len(self.output_padding):
s += ', output_padding={output_padding}'
if self.groups != 1:
s += ', groups={groups}'
if self.bias is None:
s += ', bias=False'
s += ')'
return s.format(name=self.__class__.__name__, **self.__dict__)
class Conv2d(_ConvNd):
def __init__(self, in_channels, out_channels, kernel_size, stride=1,
padding=0, dilation=1, groups=1, bias=True):
kernel_size = _pair(kernel_size)
stride = _pair(stride)
padding = _pair(padding)
dilation = _pair(dilation)
super(Conv2d, self).__init__(
in_channels, out_channels, kernel_size, stride, padding, dilation,
False, _pair(0), groups, bias)
# 修改这里的实现函数
def forward(self, input):
return conv2d_same_padding(input, self.weight, self.bias, self.stride,
self.padding, self.dilation, self.groups)
网友评论