Wie teile ich Gewichte zwischen Modulen in Pytorch?Python

Python-Programme
Guest
 Wie teile ich Gewichte zwischen Modulen in Pytorch?

Post by Guest »

Was ist der richtige Weg, Gewichte zwischen zwei Schichten (Modulen) in Pytorch zu teilen?

Basierend auf meinen Erkenntnissen im Pytorch-Diskussionsforum gibt es dafür mehrere Möglichkeiten.

Als Beispiel, basierend auf dieser Diskussion, dachte ich, dass es reichen würde, einfach die transponierten Gewichtungen zuzuweisen. Das macht:

Code: Select all

 self.decoder[0].weight = self.encoder[0].weight.t()
Dies erwies sich jedoch als falsch und verursachte einen Fehler.
Ich habe dann versucht, die obige Zeile in einen nn.Parameter() einzuschließen:

Code: Select all

self.decoder[0].weight = nn.Parameter(self.encoder[0].weight.t())
Dadurch wird der Fehler behoben, allerdings findet hier auch keine Freigabe statt. Dadurch habe ich gerade einen neuen Tensor mit den gleichen Werten wie der Encoder[0].weight.t() initialisiert.
Ich habe dann gefunden Dieser Link bietet verschiedene Möglichkeiten zum Teilen von Gewichten. Allerdings bin ich skeptisch, ob alle dort angegebenen Methoden tatsächlich korrekt sind.

Eine Möglichkeit wird beispielsweise so demonstriert:

Code: Select all

# tied autoencoder using off the shelf nn modules
class TiedAutoEncoderOffTheShelf(nn.Module):
def __init__(self, inp, out, weight):
super().__init__()
self.encoder = nn.Linear(inp, out, bias=False)
self.decoder = nn.Linear(out, inp, bias=False)

# tie the weights
self.encoder.weight.data = weight.clone()
self.decoder.weight.data = self.encoder.weight.data.transpose(0,1)

def forward(self, input):
encoded_feats = self.encoder(input)
reconstructed_output = self.decoder(encoded_feats)
return encoded_feats, reconstructed_output
Im Grunde erstellt es einen neuen Gewichtungstensor mit nn.Parameter() und weist ihn jeder Ebene/jedem Modul wie folgt zu:

Code: Select all

weights = nn.Parameter(torch.randn_like(self.encoder[0].weight))
self.encoder[0].weight.data = weights.clone()
self.decoder[0].weight.data = self.encoder[0].weight.data.transpose(0, 1)
Das verwirrt mich wirklich. Wie kommt es, dass diese beiden Ebenen dieselbe Variable gemeinsam nutzen?
Klont es nicht nur die „Rohdaten“?

Als ich diesen Ansatz verwendete und die Gewichte visualisierte, bemerkte ich, dass die Visualisierungen anders waren und das machte mich noch sicherer, dass etwas nicht stimmte.

Ich bin mir nicht sicher wenn die unterschiedlichen Visualisierungen nur darauf zurückzuführen wären, dass eine davon transponiert wurde die andere, oder wie ich gerade schon vermutet habe, werden sie unabhängig voneinander optimiert (d. h. die Gewichte werden nicht zwischen den Schichten geteilt)
Beispiel für die Gewichtsinitialisierung:
Image
Image

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post