Pytorch для неэффективности л oop - PullRequest
0 голосов
/ 20 июня 2020

У меня эффективная проблема с некоторым тензором для l oop.

Я извлекаю функции из последнего слоя CNN через загрузчик данных изображения (я использую размер пакета 8) . Я получаю евклидово расстояние тензора партии и таблицу с предыдущими характеристиками.

Я хочу добавлять в таблицу тензор каждый раз, когда все тензоры в таблице находятся выше порога. Я реализовал успешный рабочий код, но l oop я использую его неэффективно, и мне интересно, как я могу сделать что-то подобное, используя что-то более эффективное, а не этот безопасный способ.

for i, data in enumerate(dataloader, 0):
  input, label = data
  input, label = input.to(device), label.to(device)
  n,c h,w = input.size()
  outputs = model(input)
  if (i == 0):
    features_list = torch.cat( (features_list, outputs[0].view(1,-1)), 0)
  dist_tensores = torch.cdist(outputs, features_list, p=2.0)
  activation = torch.gt(dist_tensores, AVG, out=torch.cuda.FloatTensor(len(outputs), len(features_list)))
  counter = len(features_list)
  activation_list = torch.sum(activation, dim=0)
  for x in range(len(activation)):
    if (torch.sum(activation[x], dim=0) == counter):
      features_list = torch.cat( (features_list, outputs[x].view(1,-1)), 0)

Последний l oop - это часть, которую я хочу изменить, но я действительно не знаю, как назначить и добавить тензор, который мне нужен, если это не создается путем создания al oop, где я могу управлять добавляемым тензором.

Ответы [ 2 ]

0 голосов
/ 23 июня 2020
idx = activation.sum(1) == counter
features_list = torch.cat((features_list, outputs[idx]), 0)

Это заменит l oop и избавит от проблем с вычислениями и неэффективностью.

0 голосов
/ 20 июня 2020

l oop в конце неэффективен, потому что он многократно конкатенируется с одним и тем же тензором. Каждая конкатенация должна копировать весь существующий тензор, чтобы добавить еще несколько элементов в конце. Время выполнения будет квадратично c по количеству конкатенаций.

Гораздо эффективнее выполнить только одиночное конкатенацию:

outputs_to_concat = []
for x in range(len(activation)):
    if (torch.sum(activation[x], dim=0) == counter):
      outputs_to_concat.append(outputs[x].view(1,-1))
features_list = torch.cat(outputs_to_concat, dim=0)

Вот тот же код с несколькими другими чистками:

outputs_to_concat = []
for act, output in zip(activation, outputs):
    if torch.sum(act, dim=0) == counter:
        outputs_to_concat.append(output.flatten())
features_list = torch.stack(outputs_to_concat, dim=0)
...