I am trying to add some noise to the embeddings of my RoBERTa model and does not seem to succeed in doing so. I also have another interesting question which I have not been able to solve myself.
I’m trying to explore how malicious noise can affect the model training and how we can design countermeasures, for example in a wireless system.
What did I do
- I created a CustomRobertaModel
- In the forward pass, I manually get the embedding weights and add some noise to it
- Leave everything as is
This is my class:
class CustomRobertaModel(RobertaForSequenceClassification): """ Custom RoBERTa Model class that exposes embeddings, attentions, and head. """ def __init__(self, config): super().__init__(config) self.roberta_base = RobertaModel(config) self.head = self.classifier def forward(self, input_ids, attention_mask=None, token_type_ids=None, position_ids=None, head_mask=None, labels=None): with torch.no_grad(): noise = torch.normal(2, 2, size=self.roberta_base.embeddings.word_embeddings.weight.size()).to(self.roberta_base.embeddings.word_embeddings.weight.device) noisy_weights = self.roberta_base.embeddings.word_embeddings.weight + noise self.roberta_base.embeddings.word_embeddings.weight.data = noisy_weights.data # with torch.no_grad(): # self.roberta_base.embeddings.word_embeddings.weight.data.zero_() # Getting encoder outputs encoder_outputs = self.roberta( input_ids=input_ids, attention_mask=attention_mask, token_type_ids=token_type_ids, position_ids=position_ids, head_mask=head_mask ) with torch.no_grad(): self.roberta_base.embeddings.word_embeddings.weight.data.zero_() sequence_output = encoder_outputs # Passing through the classifier (head) logits = self.head(sequence_output) # Compute loss if labels are provided if labels is not None: loss = torch.nn.CrossEntropyLoss()(logits, labels) return SequenceClassifierOutput(loss=loss, logits=logits) else: return logits
I initialize using roberta-base and train as in any other tutorial.
Outcomes and Observations
- There is absolutely no change in the training and validation results in each epoch
- Even setting the embedding weights to zero as seen in above uncommented part is not effective and does absolutely nothing
- Interestingly enough, I rely on passing the input_ids instead of the embeddings to get the encoder outputs. As seen in the documentation, this is equal. However, I observe that (without any noise) my training and validation results are worst and I suspect the model is learning slower or not at all (whaat? and why?)
- Is this the right way to do it? - I want to add noise for each forward pass as if there would be a jammer sitting and adding noise to it
- What’s with the performance degradation when not using input_ids but inputs_embeds and why?
Thank you so much! Looking forward to more insights!