У меня есть следующая простая полносвязная нейронная сеть:
class Neural_net(nn.Module):
def __init__(self):
super(Neural_net, self).__init__()
self.fc1 = nn.Linear(2, 2)
self.fc2 = nn.Linear(2, 1)
self.fc_out = nn.Linear(1, 1)
def forward(self, x,train = True):
x = torch.tanh(self.fc1(x))
x = torch.tanh(self.fc2(x))
x = self.fc_out(x)
return x
net = Neural_net()
Как я могу перебрать все параметры сети и проверить, например, больше ли они определенного значения? Я использую pytorch, и если я это сделаю:
for n,p in net.named_parameters():
if p > value:
...
Я получаю сообщение об ошибке, так как p
— это не одно число, а скорее тензор весов или смещений для каждого слоя.
Моя цель - проверить, выполняется ли критерий для каждого из параметров, и пометить их, например. с 1
, если это так, или 0
, если это не так, сохраняя его в словаре с той же структурой, что и net.parameters()
. Тем не менее, у меня возникли проблемы с выяснением того, как пройти через них.
Я подумал о создании вектора параметров:
param_vec = torch.cat([p.view(-1) for p in net.parameters()])
а затем получить доступ к значениям параметров и проверить их было бы легко, но тогда я не могу придумать способ вернуться к форме словаря, чтобы пометить их.
Спасибо за любую помощь!
Сначала я бы определил критерий как операцию над тензором. В вашем случае это может выглядеть так:
cond = lambda tensor: tensor.gt(value)
Затем вам просто нужно применить его к каждому тензору в net.parameters()
. Чтобы сохранить ту же структуру, вы можете сделать это с пониманием dict
:
cond_parameters = {n: cond(p) for n,p in net.named_parameters()}
Посмотрим на практике!
net = Neural_net()
print(dict(net.parameters())
#> {'fc1.weight': Parameter containing:
#> tensor([[-0.4767, 0.0771],
#> [ 0.2874, 0.5474]], requires_grad=True),
#> 'fc1.bias': Parameter containing:
#> tensor([ 0.0405, -0.1997], requires_grad=True),
#> 'fc2.weight': Parameter containing:
#> tensor([[0.5400, 0.3241]], requires_grad=True),
#> 'fc2.bias': Parameter containing:
#> tensor([-0.5306], requires_grad=True),
#> 'fc_out.weight': Parameter containing:
#> tensor([[-0.9706]], requires_grad=True),
#> 'fc_out.bias': Parameter containing:
#> tensor([-0.4174], requires_grad=True)}
Давайте установим value
в ноль и получим список параметров:
value = 0
cond = lambda tensor: tensor.gt(value)
cond_parameters = {n: cond(p) for n,p in net.named_parameters()}
#>{'fc1.weight': tensor([[False, True],
#> [ True, True]]),
#> 'fc1.bias': tensor([ True, False]),
#> 'fc2.weight': tensor([[True, True]]),
#> 'fc2.bias': tensor([False]),
#> 'fc_out.weight': tensor([[False]]),
#> 'fc_out.bias': tensor([False])}
Это решает мою проблему, большое спасибо! похоже, что моей репутации еще недостаточно, чтобы, к сожалению, проголосовать за него :)
Еще мне было интересно, создав словарь cond_parameters, можно ли с его помощью разделить сетевые параметры на две группы в зависимости от того, является ли соответствующая запись в cond_parameters True или False?
Это, конечно, так, но вам нужно правило, чтобы определить, является ли каждая запись True/False, поскольку многие записи имеют тензоры dim>0.
Не стесняйтесь задавать новый вопрос, я сделаю все возможное, чтобы решить его :) (И вы можете получить достаточно, чтобы проголосовать)
Спасибо :) Я попробую и открою новый вопрос, если у меня возникнут проблемы.
Привет, Катерина, не могли бы вы подготовить небольшой фрагмент кода для создания игрушечного примера
net
? Таким образом, пользователи StackOverflow могут помочь вам лучше решить проблему.