Skip to content

Instantly share code, notes, and snippets.

@ShairozS
Created November 23, 2021 00:16
Show Gist options
  • Select an option

  • Save ShairozS/9481ec8da3082475292aadb55e596e5d to your computer and use it in GitHub Desktop.

Select an option

Save ShairozS/9481ec8da3082475292aadb55e596e5d to your computer and use it in GitHub Desktop.
Use a pre-trained BeRT model to create sentence embeddings
class BertEmbedder(torch.nn.Module):
def __init__(self, bert_model='bert-base-uncased'):
'''
Initialize a BeRT model and use it to create tensor sentence embeddings of length 768
Made from the guide at: https://mccormickml.com/2019/05/14/BERT-word-embeddings-tutorial/
'''
super().__init__()
self.tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
self.model = BertModel.from_pretrained('bert-base-uncased', output_hidden_states = True)
self.model.eval()
def forward(self, text):
# Run the text through BERT, and collect all of the hidden states produced
# from all 12 layers.
with torch.no_grad():
outputs = self.model(*self.preprocess(text))
# Evaluating the model will return a different number of objects based on
# how it's configured in the `from_pretrained` call earlier. In this case,
# becase we set `output_hidden_states = True`, the third item will be the
# hidden states from all layers. See the documentation for more details:
# https://huggingface.co/transformers/model_doc/bert.html#bertmodel
hidden_states = outputs[2]
token_embeddings = torch.stack(hidden_states, dim=0)
token_embeddings = torch.squeeze(token_embeddings, dim=1)
token_embeddings = token_embeddings.permute(1,0,2)
# Stores the token vectors, with shape [22 x 768]
token_vecs_sum = []
# `token_embeddings` is a [22 x 12 x 768] tensor.
# For each token in the sentence...
for token in token_embeddings:
# `token` is a [12 x 768] tensor
# Sum the vectors from the last four layers.
sum_vec = torch.sum(token[-4:], dim=0)
# Use `sum_vec` to represent `token`.
token_vecs_sum.append(sum_vec)
# `hidden_states` has shape [13 x 1 x 22 x 768]
# `token_vecs` is a tensor with shape [22 x 768]
token_vecs = hidden_states[-2][0]
# Calculate the average of all 22 token vectors.
sentence_embedding = torch.mean(hidden_states[10], 1).squeeze()
#sentence_embedding = torch.mean(token_vecs, dim=0)
return(sentence_embedding)
def preprocess(self, text):
marked_text = "[CLS] " + text + " [SEP]"
# Tokenize our sentence with the BERT tokenizer.
tokenized_text = self.tokenizer.tokenize(marked_text)
# Map the token strings to their vocabulary indeces.
indexed_tokens = self.tokenizer.convert_tokens_to_ids(tokenized_text)
# Mark each of the 22 tokens as belonging to sentence "1".
segments_ids = [1] * len(tokenized_text)
# Convert inputs to PyTorch tensors
tokens_tensor = torch.tensor([indexed_tokens])
segments_tensors = torch.tensor([segments_ids])
return(tokens_tensor, segments_tensors)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment