Das benutzerdefinierte (modifizierte) Modell in Pytorch lädt den erforderlichen Teil der Parameter des vorab trainierten Modells und friert ein

Ein Teil dieses Artikels bezieht sich auf https://zhuanlan.zhihu.com/p/34147880

1. Diese Methode ist vielseitiger: Sie lädt die Parameter des vorab trainierten Modells entsprechend den Parametern ihres eigenen Modells und weist denselben Namen zu. Wenn Sie dem Originalmodell einige Ebenen hinzufügen, wird es nicht geladen

dict_trained=torch.load(self.args.load_path, map_location=torch.device('cpu'))
dict_new=model.state_dict()
# 1. filter out unnecessary keys
dict_trained = {
    
    k: v for k, v in dict_trained.items() if k in dict_new}
# 2. overwrite entries in the existing state dict
model_dict.update(dict_trained)
model.load_state_dict(dict_new)

2. Dies ist viel komplizierter und Sie können es entsprechend Ihren eigenen Anforderungen ändern. In meinem Beispiel fügt dieses Modell beispielsweise vier Schichten hinzu: „dicht“, „unär_affin“, „binär_affin“, „Klassifikator“ und „Pass j+“. =8, überspringen Ihr Gewicht und ihre Voreingenommenheit, dies kann sich auf Gewichtsabnahme beziehen. Gleichzeitig wird der „crf“-Teil der ursprünglichen Modellparameter nicht geladen.

dict_trained = torch.load(self.args.load_path, map_location=torch.device('cpu'))
dict_new = self.model.state_dict().copy()
trained_list = list(dict_trained.keys())
new_list = list(dict_new.keys())
j = 0
no_loda = {'dense', 'unary_affine', 'binary_affine', 'classifier'}
for i in range(len(trained_list)):
     flag = False
     if 'crf' in trained_list[i]:
         continue
     for nd in no_loda:
         if nd in new_list[j] and 'bert' not in new_list[j]:
             flag = True
     if flag:
         j += 8  # no_loda的dense和bias掠过
     else:
         dict_new[new_list[j]] = dict_trained[trained_list[i]]
         if new_list[j] != trained_list[i]:
             print("i:{},new_state_dict: {}  trained state_dict: {}不一致".format(i, new_list[j], trained_list[i]))
     j += 1 #keys不对齐
model.load_state_dict(dict_new)

Später erfuhr ich, dass es einen einfacheren Weg gibt:

Das heißt, wenn Sie nach dem Einrichten Ihres eigenen Modells nur die Parameter derselben Struktur des vorab trainierten Modells verwenden möchten, setzen Sie beim Laden den Parameter strict auf False . Der Wert dieses Parameters ist standardmäßig True, was bedeutet, dass die Schicht des vorab trainierten Modells genau der Schicht der selbst definierten Netzwerkstruktur entspricht (z. B. Schichtname und -dimension), andernfalls kann sie nicht geladen werden Die Implementierung ist wie folgt:

model.load_state_dict(torch.load(self.args.load_path, strict=False))

PS: Wenn Sie auf einen Fehler stoßen, möchten Sie möglicherweise die Schlüssel der von Ihnen geänderten Modellparameter und die Schlüssel zum Laden der Modellparameter ausdrucken, um einen Blick darauf zu werfen und das richtige Medikament zu verschreiben

3. Frieren Sie diese Parameterebenen ein

Einfach gesagt

for k in model.paramers:
	k.requires_grad=False

Es gibt viele Methoden. Hier verwenden wir die Gefriermethode, die der oben genannten Methode entspricht

Es wird empfohlen, einen Blick auf
https://discuss.pytorch.org/t/how-the-pytorch-freeze-network-in-some-layers-only-the-rest-of-the-training/7088
zu werfen oder
https://discuss .pytorch.org/t/correct-way-to-freeze-layers/26714
oder
entsprechend kann während des Trainings nur der Parameter, der require_grad = True ist, im Optimierer aktualisiert werden, also

optimizer = torch.optim.Adam( filter(lambda p: p.requires_grad, net.parameters(),lr) )

Guess you like

Origin blog.csdn.net/weixin_42455006/article/details/125459110