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:
quelle
backward
? Nämlichretain_graph=True
und / odercreate_graph=True
?Antworten:
FUNKTIONIERT NICHT RICHTIG, da die genannten Parametermodule gelöscht werden.
Scheint, dass dies funktioniert:
Ausgabe:
Danksagung: mächtiger AlbanD vom Pytorch-Team: https://discuss.pytorch.org/t/how-does-one-have-the-parameters-of-a-model-not-be-leafs/70076/9?u= Pinocchio
quelle
Sie sollten versuchen, die gleichen Tensoren beizubehalten und keine neuen zu erstellen.
Suchen Sie nach ihrem
data
Attribut und legen Sie einen neuen Wert fest.Dies funktionierte für mich in dieser Frage: Wie kann man einer Pytorch-Variablen einen neuen Wert zuweisen, ohne die Backpropagation zu unterbrechen?
quelle