Почему Tensorflow имеет разные размеры для своих весов Conv2D, чем Pytorch? - PullRequest
0 голосов
/ 13 апреля 2020

Я работаю над конвертированием и старым проектом, написанным в тензорном потоке v1.13 для pytorch v1.4.0, когда я заметил, что тензорный поток и pytorch имеют весовые тензоры разного размера для 2-го cnns.

Вот мой код тензорного потока

cnn = tf.layers.conv2d(img_tensor, 16, (3, 3), (1, 1), padding='SAME', name='cnn_1')
cnn = tf.layers.conv2d(cnn, 32, (3, 3), (1, 1), padding='SAME', name='cnn_2')

init = tf.global_varaibles_initializer()
with tf.Session() as sess:
   sess.run(init)
   vars = {v.name:v for v in tf.trainable_variables()}
   print(sess.run(vars['cnn_2/kernel:0']).shape)

Результат

(3, 3, 1, 32)

Вот мой код pytorch

class Net(Module):
   def __init__(self):
      super(Net, self).__init__()
      self.create_cnn()

   def create_cnn(self):
      self.cnn_layers = Sequential(
         Conv2d(1,16,3,padding=1)
         Conv2d(16,32,3,padding=1)
      )

   def forward(self, x):
      return self.cnn_layers(x)

def weights_init(m):
   if type(m) == Conv2d:
      if(m.bias.shape[0] == 32):
         print(m.weight.data.shape)

model = Net()
model.apply(weights_init)

Результат

torch.Size([32,16,3,3])

Причина, по которой это произошло, заключалась в том, что мой Модель pytorch не работает, поэтому я начал разбирать слои по слоям и сравнивать результаты между тензорным потоком и pytorch. Чтобы это работало, мне нужно было установить веса для обеих моделей на одинаковые значения. Ну, я получил 2-й слой cnn и был сбит с толку, когда не удалось установить веса, потому что размер был неправильным. Немного возни и я нашел эту разницу.

Похоже, тензор потока использует одно и то же ядро ​​во всех каналах, где у pytorch есть уникальное ядро ​​для каждого канала. Если это так, как я могу воспроизвести это в pytorch?

1 Ответ

0 голосов
/ 14 апреля 2020

После перечитывания документации по pytorch я заметил, что свойство groups как раз связано с этим. Это научит меня не скользить по частям документов. Установив groups = in_channels, я теперь получаю размер (32, 1, 3, 3) по желанию.

Редактировать: так что еще более неловко, в моем тестовом коде я подавал свои входные данные в оба слоя cnn вместо Дейзи приковывает их цепью. Когда я действительно запускаю код, как написано выше, второй cnn в tenorflow действительно имеет веса с размером (3, 3, 16, 32).

Но, по крайней мере, я узнал о группировке.

...