美文网首页
Pytorch实现TensorFlow中的Padding策略

Pytorch实现TensorFlow中的Padding策略

作者: ColleenKuang | 来源:发表于2019-12-22 23:49 被阅读0次

目录

  1. 浅析Pytorch中的Padding策略
  2. 浅析Tensorflow中的Padding策略
  3. 代码实现

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模式分为两种,分别为SAMEVALID
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)

Reference

  1. What is the difference between 'SAME' and 'VALID' padding in tf.nn.max_pool of tensorflow?

相关文章

网友评论

      本文标题:Pytorch实现TensorFlow中的Padding策略

      本文链接:https://www.haomeiwen.com/subject/qtionctx.html