Ожидаемый шаг - одно целочисленное значение или список из 1 значений в соответствии с размерами свертки, но получен шаг = [1, 1] - PullRequest
0 голосов
/ 17 апреля 2020

Я прочитал этот вопрос , но, похоже, он не отвечает на мой вопрос: (.

Так что в основном я пытаюсь векторизовать игровую змею, чтобы она могла работать быстрее. Вот мой код до настоящего времени:

import torch
import torch.nn.functional as F
device = torch.device("cpu")
class SnakeBoard:
  def __init__(self, board=None):
    if board != None:
      self.channels = board
    else:
      # 0 - Food, 1 - Head, 2 - Body
      self.channels = torch.zeros(1, 3, 15, 17,
                                  device=device)

      # Initialize game channels
      self.channels[:, 0, 7, 12] = 1
      self.channels[:, 1, 7, 5] = 1
      self.channels[:, 2, 7, 2:6] = torch.arange(1, 5)
    self.move()

  def move(self):
    self.channels[:, 2] -= 1
    F.relu(self.channels[:, 2], inplace=True)
    # Up movement test
    F.conv2d(self.channels[:, 1], torch.tensor([[[0,1,0],[0,0,0],[0,0,0]]]), padding=1)

SnakeBoard()

Первое измерение в каналах представляет размер партии, второе измерение представляет 3 канала игры со змеями: еда, голова и тело, и, наконец, третье и четвертое измерения представляют высоту и ширина доски.

К сожалению, при выполнении кода я получаю сообщение об ошибке: Ожидается, что шаг будет одним целочисленным значением или списком из 1 значений в соответствии с размерами свертки, но получен шаг = [1, 1]

Как я могу это исправить?

1 Ответ

1 голос
/ 17 апреля 2020

Размеры входов для свертки не верны для двумерной свертки. Давайте посмотрим на размеры, которые вы передаете F.conv2d:

self.channels[:, 1].size()
# => torch.Size([1, 15, 17])
torch.tensor([[[0,1,0],[0,0,0],[0,0,0]]]).size()
# => torch.Size([1, 3, 3])

Правильные размеры должны быть

  • input : (размер пакета, in_channels, высота, ширина)
  • вес : (out_channels, in_channels, kernel_height, kernel_width)

Поскольку ваш вес имеет только 3 измерения, он считается 1-мерной сверткой, но поскольку вы назвали F.conv2d, шаг и отступы будут кортежами и, следовательно, не будут работать.

Для ввода вы проиндексировали второе измерение, которое выбирает этот конкретный элемент по этим измерениям и удаляет эти измерения. Чтобы сохранить это измерение, вы можете проиндексировать его только одним элементом. И для веса вам не хватает одного измерения, которое можно просто добавить напрямую. Также ваш вес имеет тип torch.long, так как вы используете только целые числа при создании тензора, но вес должен быть типа torch.float.

F.conv2d(self.channels[:, 1:2], torch.tensor([[[[0,1,0],[0,0,0],[0,0,0]]]], dtype=torch.float), padding=1)

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

Например, гораздо проще добиться увеличения, убрав первую строку и добавив новую строку нулей. в конце все сдвигается вверх (при условии, что первый ряд является верхним, а последний - нижним).

head = self.channels[:, 1:2]
batch_size, channels, height, width = head.size()
# Take everything but the first row of the head
# Add a row of zeros to the end by concatenating them across the height (dimension 2)
new_head = torch.cat([head[:, :, 1:], torch.zeros(batch_size, channels, 1, width)], dim=2)

# Or if you want to wrap it around the board, it's even simpler.
# Move the first row to the end
wrap_around_head = torch.cat([head[:, :, 1:], head[:, :, 0:1]], dim=2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...