Скопируйте веса одного слоя из одной модели Huggingface BERT в другую

#python #bert-language-model #huggingface-transformers

Вопрос:

У меня есть предварительно обученная модель, которую я загружаю так:

 from transformers import BertForSequenceClassification, AdamW, BertConfig, BertModel
model = BertForSequenceClassification.from_pretrained(
    "bert-base-uncased", # Use the 12-layer BERT model, with an uncased vocab.
    num_labels = 2, # The number of output labels--2 for binary classification.
                    # You can increase this for multi-class tasks.   
    output_attentions = False, # Whether the model returns attentions weights.
    output_hidden_states = False, # Whether the model returns all hidden-states.
)
 

Я хочу создать новую модель с той же архитектурой и случайными начальными весами, за исключением слоя встраивания:

 ==== Embedding Layer ====

bert.embeddings.word_embeddings.weight                  (30522, 768)
bert.embeddings.position_embeddings.weight                (512, 768)
bert.embeddings.token_type_embeddings.weight                (2, 768)
bert.embeddings.LayerNorm.weight                              (768,)
bert.embeddings.LayerNorm.bias                                (768,)
 

Кажется, я могу сделать это, чтобы создать новую модель с той же архитектурой, но тогда все веса будут случайными:

 configuration   = model.config
untrained_model = BertForSequenceClassification(configuration)
 

Итак, как мне скопировать model веса встраиваемого слоя в новый untrained_model ?

Ответ №1:

Веса и смещение-это просто тензор, и вы можете просто скопировать их с помощью copy_:

 from transformers import BertForSequenceClassification, BertConfig
jetfire = BertForSequenceClassification.from_pretrained('bert-base-cased')
config = BertConfig.from_pretrained('bert-base-cased')

optimus = BertForSequenceClassification(config)

parts = ['bert.embeddings.word_embeddings.weight'
,'bert.embeddings.position_embeddings.weight'              
,'bert.embeddings.token_type_embeddings.weight'    
,'bert.embeddings.LayerNorm.weight'
,'bert.embeddings.LayerNorm.bias']

def joltElectrify (jetfire, optimus, parts):
  target = dict(optimus.named_parameters())
  source = dict(jetfire.named_parameters())

  for part in parts:
    target[part].data.copy_(source[part].data)  

joltElectrify(jetfire, optimus, parts)
 

Комментарии:

1. Кажется, это работает. Спасибо! Единственное, чем я отличался от тебя, так это тем, что я все еще configuration = model.config; untrained_model = BertForSequenceClassification(configuration) копировал предварительно подготовленную модель

2. Ты тоже можешь это сделать. Я просто сделал это таким образом, чтобы показать, что вы можете использовать что угодно в качестве config . @RussellRichie