Пользовательское ядро ​​свертки и тороидальная свертка в PyTorch - PullRequest
0 голосов
/ 01 июня 2018

Я хочу сделать две вещи с помощью свертки PyTorch, которые не упомянуты в документации или коде:

  1. Я хочу создать свертку сисправлено ядро, как это:

    000010000
    000010000
    100010001
    000010000
    000010000
    

    Горизонтальный аспект похож на расширение, я думаю, но вертикальная часть отличается.Я вижу, что расширение доступно в качестве параметра в коде, но это должен быть скалярный или одноэлементный кортеж (не один элемент на измерение), поэтому я не думаю, что он может делать то, что я хочу здесь.

  2. Я бы хотел, чтобы мои свертки "обвивались" как тороид, а не использовали набивку.

    РЕДАКТИРОВАТЬ ДОБАВИТЬ: Я вижу, что для этого существует открытый выпуск , который также обеспечивает неоптимальный обходной путь .Итак, я думаю, что пока нет «правильного» способа сделать это.

1 Ответ

0 голосов
/ 01 июня 2018
  1. В отличие от torch.nn.conv2d() (который создает собственное обучаемое ядро), torch.nn.functional.conv2d() принимает в качестве параметров как матрицу, так и ядро, поэтому вы можете передатьэто любое пользовательское ядро, которое вы хотите.

  2. Как предложено @ zou3519 в выпуске Github (связан с выпуском Вы упомянули себя), вы можете реализовать 2D циклическое заполнение, " повторяя тензор в сетке nxn, затем обрезая нужную вам часть. ":

def circular_pad_2d(x, pad=(1, 1)):
   # Snipped by @zou3519 (https://github.com/zou3519)
   return x.repeat(*x_shape[:2])[
        (x.shape[0]-pad[0]):(2*x.shape[0]+pad[0]), 
        (x.shape[1]-pad[1]):(2*x.shape[1]+pad[1])
   ]

# Example:
x = torch.tensor([[1,2,3],[4,5,6]])
y = circular_pad_2d(x, pad=(2, 3))
print(y)
#     1     2     3     1     2     3     1     2     3
#     4     5     6     4     5     6     4     5     6
#     1     2     3     1     2     3     1     2     3
#     4     5     6     4     5     6     4     5     6

(предыдущий) В модуле torch.nn.functional также torch.nn.functional.pad() может принимать в качестве параметра mode=reflect, что, как я полагаю, вы хотите(?).Вы можете использовать этот метод, чтобы вручную заполнить вашу матрицу ввода перед выполнением свертки. (примечание: у вас также есть слой torch.nn.ReflectionPad2d, специально предназначенный для фиксированного 2D-заполнения отражением)
...