Мой PyTorch Conv1d с идентификатором ядра не выдает тот же вывод, что и ввод - PullRequest
1 голос
/ 21 марта 2020

У меня есть:

        print('\ninp', inp.min(), inp.mean(), inp.max())
        print(inp)
        out = self.conv1(inp)
        print('\nout1', out.min(), out.mean(), out.max())
        print(out)
        quit()

Мои минимальные, средние и максимальные значения для моего входного файла: inp tensor(9.0060e-05) tensor(0.1357) tensor(2.4454)

Для моего выходного значения я имею: out1 tensor(4.8751, grad_fn=<MinBackward1>) tensor(21.8416, grad_fn=<MeanBackward0>) tensor(54.9332, grad_fn=<MaxBackward1>)

Мой self.conv1:

        self.conv1 = torch.nn.Conv1d(
            in_channels=161,
            out_channels=161,
            kernel_size=11,
            stride=1,
            padding=5)
        self.conv1.weight.data = torch.zeros(self.conv1.weight.data.size())
        self.conv1.weight.data[:, :, 5] = 1.0
        self.conv1.bias.data = torch.zeros(self.conv1.bias.data.size())

Итак, мои веса выглядят следующим образом: tensor([0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.])

Так что, если я пойму, как работает свертка, это должно привести к тому же результату. Но это не так.

Что я делаю не так?

1 Ответ

3 голосов
/ 21 марта 2020

Всегда старайтесь предоставить Минимальный воспроизводимый пример .


Это не должно. Возможно, вы забыли суммирование. Как указано в документах :

В простейшем случае, выходное значение слоя с входным размером (N, C_in, L) и выходным (N, C_out, L_out) ) можно точно описать следующим образом: equation

где ⋆ - действительный оператор взаимной корреляции, N - размер пакета, C - количество каналов, L - длина сигнальной последовательности.

Обратите внимание, что в вашем примере среднее значение после conv (т.е. 21.8416) составляет прибл. 161 раз выше среднего (т.е. 161 * 0.1357), и это не случайно. Обратите внимание, что то же самое происходит в коде ниже:

import torch
torch.manual_seed(0)

# define the fake input data
x = torch.rand(1, 3, 5)
# >>> x
# tensor([[[0.4963, 0.7682, 0.0885, 0.1320, 0.3074],
#          [0.6341, 0.4901, 0.8964, 0.4556, 0.6323],
#          [0.3489, 0.4017, 0.0223, 0.1689, 0.2939]]])

# define the conv
conv1 = torch.nn.Conv1d(3, 3, kernel_size=5, stride=1, padding=2)
conv1.weight.data = torch.zeros(conv1.weight.data.size())
conv1.weight.data[:, :, 2] = 1.0
conv1.bias.data = torch.zeros(conv1.bias.data.size())

# print mean before
print(x.mean())
# tensor(0.4091)

# print mean after
print(conv1(x).mean())
# tensor(1.2273, grad_fn=<MeanBackward0>)

Видите? После конва среднее значение будет в 3 раза больше исходного.

Как сказал @jodag, если вы хотите личность, вы можете сделать так:

import torch
torch.manual_seed(0)

# define the fake input data
x = torch.rand(1, 3, 5)
# >>> x
# tensor([[[0.4963, 0.7682, 0.0885, 0.1320, 0.3074],
#          [0.6341, 0.4901, 0.8964, 0.4556, 0.6323],
#          [0.3489, 0.4017, 0.0223, 0.1689, 0.2939]]])

# define the conv
conv1 = torch.nn.Conv1d(3, 3, kernel_size=5, stride=1, padding=2)
torch.nn.init.zeros_(conv1.weight)
torch.nn.init.zeros_(conv1.bias)
# set identity kernel
conv1.weight.data[:, :, 2] = torch.eye(3, 3)

# print mean before
print(x.mean())
# tensor(0.4091)

# print mean after
print(conv1(x).mean())
# tensor(0.4091, grad_fn=<MeanBackward0>)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...