Форма pytorch model.parameter не соответствует тому, как он определен в модели - PullRequest
0 голосов
/ 25 ноября 2018

Я пытаюсь извлечь весовые коэффициенты из простой сети, построенной в PyTorch.Вся моя сеть состоит из nn. Линейных слоев.Когда я создаю слой, вызывая nn.Linear(in_dim, out_dim), я ожидаю, что параметры, полученные из вызова model.parameters() для этой модели, будут иметь форму (in_dim, out_dim) для веса и (out_dim) для смещения.Однако веса, которые получаются из model.parameters(), вместо формы (out_dim, in_dim).

Цель моего кода - иметь возможность использовать умножение матриц для выполнения прямого прохода, используя только numpy, а не PyTorch.,Из-за несогласованности форм умножение матриц выдает ошибку.Как я могу это исправить?

Вот мой точный код:

class RNN(nn.Module):

    def __init__(self, dim_input, dim_recurrent, dim_output):

        super(RNN, self).__init__()

        self.dim_input = dim_input
        self.dim_recurrent = dim_recurrent
        self.dim_output = dim_output

        self.dense1 = nn.Linear(self.dim_input, self.dim_recurrent)
        self.dense2 = nn.Linear(self.dim_recurrent, self.dim_recurrent, bias = False)
        self.dense3 = nn.Linear(self.dim_input, self.dim_recurrent)
        self.dense4 = nn.Linear(self.dim_recurrent, self.dim_recurrent, bias = False)
        self.dense5 = nn.Linear(self.dim_recurrent, self.dim_output)

#There is a defined forward pass

model = RNN(12, 100, 6)

for i in model.parameters():
    print(i.shape())

Вывод:

torch.Size([100, 12])
torch.Size([100])
torch.Size([100, 100])
torch.Size([100, 12])
torch.Size([100])
torch.Size([100, 100])
torch.Size([6, 100])
torch.Size([6])

Вывод должен, если я прав,быть:

torch.Size([12, 100])
torch.Size([100])
torch.Size([100, 100])
torch.Size([12, 100])
torch.Size([100])
torch.Size([100, 100])
torch.Size([100, 6])
torch.Size([6])

В чем моя проблема?

1 Ответ

0 голосов
/ 25 ноября 2018

То, что вы видите, это не (out_dim, in_dim), это просто форма матрицы весов.Когда вы звоните print(model), вы видите, что функции ввода и вывода правильны:

RNN(
  (dense1): Linear(in_features=12, out_features=100, bias=True)
  (dense2): Linear(in_features=100, out_features=100, bias=False)
  (dense3): Linear(in_features=12, out_features=100, bias=True)
  (dense4): Linear(in_features=100, out_features=100, bias=False)
  (dense5): Linear(in_features=100, out_features=6, bias=True)
)

Вы можете проверить исходный код, чтобы увидеть, что веса на самом деле транспонированы перед вызовом matmul.


nn.Linear определяется здесь:
https://pytorch.org/docs/stable/_modules/torch/nn/modules/linear.html#Linear

Вы можете проверить forward, это выглядит так:

def forward(self, input):
    return F.linear(input, self.weight, self.bias)


F.linear здесь определено:
https://pytorch.org/docs/stable/_modules/torch/nn/functional.html

Соответствующиелиния для умножения весов:

output = input.matmul(weight.t())

Как уже упоминалось выше, вы можете видеть, что весов транспонированы перед применением matmul и, следовательно, формавес отличается от того, что вы ожидали.

Итак, если вы хотите выполнить умножение матриц вручную, вы сделаете:

# dummy input of length 5
input = torch.rand(5, 12)
# apply layer dense1 (without bias, for bias just add + model.dense1.bias)
output_first_layer = input.matmul(model.dense1.weight.t())
print(output_first_layer.shape)

Так же, как вы ожидаете от вашего dense1, он возвращает:

torch.Size([5, 100])

Надеюсь, это объясняет ваши наблюдения формой:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...