たれぱんのびぼーろく

わたしの備忘録、生物学とプログラミングが多いかも

パディング/padding in PyTorch

幅のある入力をスライドさせながら処理していくとき、左右端をどうするかという問題がでてくる。
端を何かしらの値で埋める(入力をちょっと大きくしておく)処理をパディングという。
特にPyTorchにおけるパディング実装のまとめ。

F.pad

torch.nn.functional.pad(input, pad, mode='constant', value=0.0)
これが本丸、ユーザーもPyTorch内部もこれを使う。

pad - (len_L0Left, len_L0Right, len_L1Left, len_L1Right, len_L2Left, len_L2Right, ...)

Convのpadding内部実装

F.padpad引数を内部で組み立て、call時にF.padしてる。

# pytorch/torch/nn/modules/conv.py

# https://github.com/pytorch/pytorch/blob/4e1f41f66aa960f15dce94ee062479b3eb881ddb/torch/nn/modules/conv.py#L89-L92
## Confirming padding == 'same' | 'valid'
        valid_padding_strings = {'same', 'valid'}
        if isinstance(padding, str):
            if padding not in valid_padding_strings:
                raise ValueError(
...
# https://github.com/pytorch/pytorch/blob/4e1f41f66aa960f15dce94ee062479b3eb881ddb/torch/nn/modules/conv.py#L106
        self.padding = padding
...
# https://github.com/pytorch/pytorch/blob/4e1f41f66aa960f15dce94ee062479b3eb881ddb/torch/nn/modules/conv.py#L116-L125
## Generating F.pad's `pad` argument (each element specify padding length)
        if isinstance(self.padding, str):
            ## No padding in all dimension when "valid"
            self._reversed_padding_repeated_twice = [0, 0] * len(kernel_size)
            ## Size-keep padding based on dilation & kernel (prerequisite: stride==1) when "same"
            if padding == 'same':
                # For each dimension
                for d, k, i in zip(dilation, kernel_size,
                                   range(len(kernel_size) - 1, -1, -1)):
                    # total_padding == left_pad + right_pad
                    total_padding = d * (k - 1)
                    # For indivisible total padding (results in uneven left/right padding)
                    left_pad = total_padding // 2
                    # even index: left
                    self._reversed_padding_repeated_twice[2 * i] = left_pad
                    # odd index: right
                    self._reversed_padding_repeated_twice[2 * i + 1] = (
                    # `total_padding - left_pad` is right_pad
                        total_padding - left_pad)

LRで異なるpadding値を明示的に設定する機能は備わっていない。