Ich versuche, die Parameter eines neuronalen Netzmodells zu aktualisieren / zu ändern und dann den Vorwärtsdurchlauf des aktualisierten neuronalen Netzes im Berechnungsdiagramm zu haben (unabhängig davon, wie viele Änderungen / Aktualisierungen wir vornehmen).
Ich habe diese Idee ausprobiert, aber wann immer ich es tue, setzt pytorch meine aktualisierten Tensoren (innerhalb des Modells) auf Blätter, wodurch der Fluss von Gradienten zu den Netzwerken, die ich Gradienten empfangen möchte, unterbrochen wird. Der Fluss von Verläufen wird unterbrochen, da Blattknoten nicht so Teil des Berechnungsdiagramms sind, wie ich sie haben möchte (da sie keine echten Blätter sind).
Ich habe mehrere Dinge ausprobiert, aber nichts scheint zu funktionieren. Ich habe einen eigenständigen Dummy-Code erstellt, der die Verläufe der Netzwerke druckt, für die ich Verläufe haben möchte:
import torch
import torch.nn as nn
import copy
from collections import OrderedDict
# img = torch.randn([8,3,32,32])
# targets = torch.LongTensor([1, 2, 0, 6, 2, 9, 4, 9])
# img = torch.randn([1,3,32,32])
# targets = torch.LongTensor([1])
x = torch.randn(1)
target = 12.0*x**2
criterion = nn.CrossEntropyLoss()
#loss_net = nn.Sequential(OrderedDict([('conv0',nn.Conv2d(in_channels=3,out_channels=10,kernel_size=32))]))
loss_net = nn.Sequential(OrderedDict([('fc0', nn.Linear(in_features=1,out_features=1))]))
hidden = torch.randn(size=(1,1),requires_grad=True)
updater_net = nn.Sequential(OrderedDict([('fc0',nn.Linear(in_features=1,out_features=1))]))
print(f'updater_net.fc0.weight.is_leaf = {updater_net.fc0.weight.is_leaf}')
#
nb_updates = 2
for i in range(nb_updates):
print(f'i = {i}')
new_params = copy.deepcopy( loss_net.state_dict() )
## w^<t> := f(w^<t-1>,delta^<t-1>)
for (name, w) in loss_net.named_parameters():
print(f'name = {name}')
print(w.size())
hidden = updater_net(hidden).view(1)
print(hidden.size())
#delta = ((hidden**2)*w/2)
delta = w + hidden
wt = w + delta
print(wt.size())
new_params[name] = wt
#del loss_net.fc0.weight
#setattr(loss_net.fc0, 'weight', nn.Parameter( wt ))
#setattr(loss_net.fc0, 'weight', wt)
#loss_net.fc0.weight = wt
#loss_net.fc0.weight = nn.Parameter( wt )
##
loss_net.load_state_dict(new_params)
#
print()
print(f'updater_net.fc0.weight.is_leaf = {updater_net.fc0.weight.is_leaf}')
outputs = loss_net(x)
loss_val = 0.5*(target - outputs)**2
loss_val.backward()
print()
print(f'-- params that dont matter if they have gradients --')
print(f'loss_net.grad = {loss_net.fc0.weight.grad}')
print('-- params we want to have gradients --')
print(f'hidden.grad = {hidden.grad}')
print(f'updater_net.fc0.weight.grad = {updater_net.fc0.weight.grad}')
print(f'updater_net.fc0.bias.grad = {updater_net.fc0.bias.grad}')
Wenn jemand weiß, wie das geht, gib mir bitte einen Ping ... Ich habe die Anzahl der zu aktualisierenden Male auf 2 gesetzt, da der Aktualisierungsvorgang beliebig oft im Berechnungsdiagramm sein sollte ... also MUSS es funktionieren 2.
Stark verwandter Beitrag:
- DAMIT: Wie kann man Parameter in einem Pytorch-Modell nicht als Blätter und im Berechnungsdiagramm haben?
- pytorch forum: https://discuss.pytorch.org/t/how-does-one-have-the-parameters-of-a-model-not-be-leafs/70076
Cross-posted:
backward
? Nämlichretain_graph=True
und / odercreate_graph=True
?