幅のある入力をスライドさせながら処理していくとき、左右端をどうするかという問題がでてくる。
端を何かしらの値で埋める(入力をちょっと大きくしておく)処理をパディングという。
特に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.pad
のpad
引数を内部で組み立て、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値を明示的に設定する機能は備わっていない。