Несоответствие между константой тензорного потока и константой питорча - PullRequest
1 голос
/ 01 июля 2019

Я пытаюсь импортировать некоторый код pytorch в tenorflow, я узнал, что torch.nn.functional.conv1d () - это tf.nn.conv1d (), но я боюсь, что в версиях tf все еще есть некоторые расхождения.В частности, я не могу найти параметр группы в tf.conv1d.Например: следующие коды выводят два разных результата:

Pytorch:

inputs = torch.Tensor([[[1, 1, 1, 1],[2, 2, 2, 2],[3, 3, 3, 3]]]) #batch_sizex seq_length x embed_dim, 
inputs = inputs.transpose(2,1) #batch_size x embed_dim x seq_length
batch_size, embed_dim, seq_length = inputs.size()

kernel_size = 3
in_channels = 2
out_channels = in_channels 
weight = torch.ones(out_channels, 1, kernel_size)

inputs = inputs.contiguous().view(-1, in_channels, seq_length) #batch_size*embed_dim/in_channels x in_channels x seq_length 
inputs = F.pad(inputs, (kernel_size-1,0), 'constant', 0)
output = F.conv1d(inputs, weight, padding=0, groups=in_channels)
output = output.contiguous().view(batch_size, embed_dim, seq_length).transpose(2,1)

Выход:

tensor([[[1., 1., 1., 1.],
         [3., 3., 3., 3.],
         [6., 6., 6., 6.]]])

Tensorflow:

inputs = tf.constant([[[1, 1, 1, 1],[2, 2, 2, 2],[3, 3, 3, 3]]], dtype=tf.float32) #batch_sizex seq_length x embed_dim
inputs = tf.transpose(inputs, perm=[0,2,1])
batch_size, embed_dim, seq_length = inputs.get_shape()

print(batch_size, seq_length, embed_dim)
kernel_size = 3
in_channels = 2
out_channels = in_channels 
weight = tf.ones([kernel_size, in_channels, out_channels])

inputs = tf.reshape(inputs, [(batch_size*embed_dim)//in_channels, in_channels, seq_length], name='inputs')
inputs = tf.transpose(inputs, perm=[0, 2, 1])
padding = [[0, 0], [(kernel_size - 1), 0], [0, 0]]
padded = tf.pad(inputs, padding)

res = tf.nn.conv1d(padded, weight, 1, 'VALID')
res = tf.transpose(res, perm=[0, 2, 1])
res = tf.reshape(res, [batch_size, embed_dim, seq_length])
res = tf.transpose(res, perm=[0, 2, 1])
print(res)

Выход:

[[[ 2.  2.  2.  2.]
  [ 6.  6.  6.  6.]
  [12. 12. 12. 12.]]], shape=(1, 3, 4), dtype=float32)

1 Ответ

2 голосов
/ 01 июля 2019

Разные результаты

Между этими версиями нет расхождений, вы просто настраиваете разные вещи.Чтобы получить те же результаты, что и в Tensorflow, измените строки с весами на:

weight = torch.ones(out_channels, 2, kernel_size)

, потому что у вашего входа есть два входных канала, как вы правильно объявили в TF:

weight = tf.ones([kernel_size, in_channels, out_channels])

Параметр групп

Вы неправильно поняли, за что отвечает параметр groups в pytorch.Он ограничивает количество каналов, используемых каждым фильтром (в данном случае только один, поскольку 2 input_channels, разделенные на 2, дают нам один).

См. здесь для более интуитивного объяснения 2Dсвертка.

...