Pytorch, как изменить/уменьшить количество фильтров без изменения формы отдельных фильтров

Как с трехмерным тензором формы (количество фильтров, высота, ширина) можно уменьшить количество фильтров с изменением формы, которое сохраняет исходные фильтры вместе как целые блоки?

Предположим, что размеры нового размера выбраны таким образом, что целое число исходных фильтров может поместиться рядом в одном из новых фильтров. Таким образом, исходный размер (4, 2, 2) можно преобразовать в (2, 2, 4).

Визуальное объяснение изменения формы рядом, где вы видите стандартное изменение формы, изменит отдельные формы фильтра:

Я пробовал различные функции pytorch, такие как gather и select_index, но не нашел способа получить конечный результат в общем виде (т.е. работает для разного количества фильтров и разных размеров фильтров).

Я думаю, что было бы проще изменить значения тензора после изменения формы, но не смог получить тензор измененной формы pytorch:

[[[1,2,3,4],
  [5,6,7,8]],
 
 [[9,10,11,12],
  [13,14,15,16]]]

К:

[[[1,2,5,6],
  [3,4,7,8]],

 [[9,10,13,14],
  [11,12,15,16]]]

Для полноты исходный тензор перед изменением формы:

[[[1,2],
  [3,4]],
 
 [[5,6],
  [7,8]],

 [[9,10],
  [11,12]],

 [[13,14],
  [15,16]]]
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
2
0
311
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете сделать это, разбивая тензор, а затем рекомбинируя.

def side_by_side_reshape(x):
    n_pairs = x.shape[0] // 2
    filter_size = x.shape[-1]
    x = x.reshape((n_pairs, 2, filter_size, filter_size))
    return torch.stack(list(map(lambda x: torch.hstack(x.unbind()), k)))
>> p = torch.arange(1, 91).reshape((10, 3, 3))
>> side_by_side_reshape(p)

tensor([[[ 1,  2,  3, 10, 11, 12],
         [ 4,  5,  6, 13, 14, 15],
         [ 7,  8,  9, 16, 17, 18]],

        [[19, 20, 21, 28, 29, 30],
         [22, 23, 24, 31, 32, 33],
         [25, 26, 27, 34, 35, 36]],

        [[37, 38, 39, 46, 47, 48],
         [40, 41, 42, 49, 50, 51],
         [43, 44, 45, 52, 53, 54]],

        [[55, 56, 57, 64, 65, 66],
         [58, 59, 60, 67, 68, 69],
         [61, 62, 63, 70, 71, 72]],

        [[73, 74, 75, 82, 83, 84],
         [76, 77, 78, 85, 86, 87],
         [79, 80, 81, 88, 89, 90]]])

Но я знаю, что это не идеально, так как есть map, list и unbind, которые нарушают память. Это то, что я предлагаю, пока не выясню, как это сделать только через просмотр (так что настоящее изменение)

Ответ принят как подходящий

Другой вариант — создать список частей и соединить их.

x = torch.arange(4).reshape(4, 1, 1).repeat(1, 2, 2)
y = torch.cat([x[i::2] for i in range(2)], dim=2)

print('Before\n', x)
print('After\n', y)

Который дает

Before
 tensor([[[0, 0],
         [0, 0]],

        [[1, 1],
         [1, 1]],

        [[2, 2],
         [2, 2]],

        [[3, 3],
         [3, 3]]])
After
 tensor([[[0, 0, 1, 1],
         [0, 0, 1, 1]],

        [[2, 2, 3, 3],
         [2, 2, 3, 3]]])

Или, в более общем смысле, мы могли бы написать функцию, которая берет группы соседей по исходному измерению и объединяет их по целевому измерению.

def group_neighbors(x, group_size, src_dim, dst_dim):
    assert x.shape[src_dim] % group_size == 0
    return torch.cat([x[[slice(None)] * (src_dim) + [slice(i, None, group_size)] + [slice(None)] * (len(x.shape) - (src_dim + 2))] for i in range(group_size)], dim=dst_dim)


x = torch.arange(4).reshape(4, 1, 1).repeat(1, 2, 2)
# read as "take neighbors in groups of 2 from dimension 0 and concatenate them in dimension 2"
y = group_neighbors(x, group_size=2, src_dim=0, dst_dim=2)

print('Before\n', x)
print('After\n', y)

Другие вопросы по теме