Ошибка времени выполнения: заданные группы = 1, вес размера [32, 1, 3, 3], ожидалось, что входные данные [1, 3, 6, 7] будут иметь 1 канал, но вместо этого получили 3 канала

#numpy #pytorch

#numpy #pytorch

Вопрос:

Существует массив numpy размером 6×7:

 <class 'numpy.ndarray'>
[[[0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]]]
 

Модель обучается нормально, когда она передается в эту сеть:

 class Net(BaseFeaturesExtractor):
    def __init__(self, observation_space: gym.spaces.Box, features_dim: int = 256):
        super(Net, self).__init__(observation_space, features_dim)
        # We assume CxHxW images (channels first)
        # Re-ordering will be done by pre-preprocessing or wrapper
        # n_input_channels = observation_space.shape[0]
        n_input_channels = 1
        print("Input channels:", n_input_channels)
        self.cnn = nn.Sequential(
            nn.Conv2d(n_input_channels, 32, kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=0),
            nn.ReLU(),
            nn.Flatten(),
        )

        # Compute shape by doing one forward pass
        with th.no_grad():
            n_flatten = self.cnn(
                th.as_tensor(observation_space.sample()[None]).float()
            ).shape[1]

        self.linear = nn.Sequential(nn.Linear(n_flatten, features_dim), nn.ReLU())

    def forward(self, observations: th.Tensor) -> th.Tensor:
        return self.linear(self.cnn(observations))
 

массив numpy размером 6×7 изменен на массив numpy размером 3x6x7:

 <class 'numpy.ndarray'>

[[[0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]]

 [[0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]]

 [[0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [1 1 1 1 1 1 1]]]
 

После изменения массива он выдает эту ошибку:

Ошибка времени выполнения: заданные группы = 1, вес размера [32, 1, 3, 3], ожидалось, что входные данные [1, 3, 6, 7] будут иметь 1 канал, но вместо этого получили 3 канала

Чтобы решить эту проблему, я попытался изменить количество каналов:

 n_input_channels = 3
 

Однако теперь он показывает эту ошибку:

Ошибка времени выполнения: заданные группы = 1, вес размера [32, 3, 3, 3], ожидалось, что входные данные [1, 1, 6, 7] будут иметь 3 канала, но вместо этого получили 1 канал

Как я могу заставить сеть принимать массив 3x6x7?

Обновление: я предоставляю больше кода, чтобы прояснить мой случай:

входной массив 6×7:

 ...
board = np.array(self.obs['board']).reshape(1, self.rows, self.columns)
# board = board_3layers(self.obs.mark, board)
print(type(board))
print(board)
return board
 

Вывод:

 <class 'numpy.ndarray'>
[[[0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]]]
 

Количество каналов равно 3:

 n_input_channels = 1
 

Он работает.

Я пытаюсь изменить массив на 3x6x7:

 board = np.array(self.obs['board']).reshape(1, self.rows, self.columns)
board = board_3layers(self.obs.mark, board)
print(type(board))
print(board)
return board
 

Вывод:

 <class 'numpy.ndarray'>
[[[0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]]

 [[0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]]

 [[0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0]
  [1 1 1 1 1 1 1]]]
 

Количество каналов равно 3:

     n_input_channels = 3
 

Я не понимаю, почему он показывает эту ошибку:

 RuntimeError: Given groups=1, weight of size [32, 3, 3, 3], expected input[1, 1, 6, 7] to have 3 channels, but got 1 channels instead
 

Ответ №1:

Ваша модель может работать либо с 1-канальным входом, либо с 3-канальным входом, но не с обоими.

Если вы установите n_input_channels=1 , вы можете работать с 1x6x7 входными массивами.
Если вы установите n_input_channels=3 , вы можете работать с 3x6x7 входными массивами.

Вы должны выбрать один из вариантов — вы не можете использовать их оба одновременно.

Комментарии:

1. спасибо за ваш ответ. Я хочу работать с входным массивом 3x6x7. Как я уже писал в вопросе, я получаю ошибку: RuntimeError: заданные группы = 1, вес размера [32, 3, 3, 3], ожидалось, что входные данные [1, 1, 6, 7] будут иметь 3 канала, но вместо этого получили 1 канал. Я хочу, чтобы сеть принимала входной массив размером 3x6x7

2. @JoeRakhimov вы установили n_input_channels=3 , но используемый вами входной массив был 6x7 , а не 3x6x7 — вот что говорится в сообщении об ошибке, которое вы получили.

3. Я думаю, что я использую входной массив 3x6x7. Я добавил код, как я это делаю. Пожалуйста, посмотрите в части обновления

4. еще раз спасибо за ваш ответ, проблема была в другом месте. У меня есть это: shape=(1, self.строки, self.столбцы). Изменен на эту форму =(3, self.строки, self.столбцы). Теперь он работает